# HG changeset patch # User Sergey Kandaurov # Date 1466152593 -10800 # Node ID 4dc302d8e04fceb45525f7779fa2a018d987d49c # Parent b9e42c554ba713853bf0c507be27bf7fb9076d17 Tests: changed HTTP2 package to act as a class. Stopped exporting any subroutines. A subset of them now act as class methods. diff --git a/h2.t b/h2.t --- a/h2.t +++ b/h2.t @@ -18,7 +18,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame :io /; +use Test::Nginx::HTTP2; ############################################################################### @@ -187,8 +187,8 @@ like($r, qr!Upgrade: h2c!, 'upgrade - to # SETTINGS -my $sess = new_session(8080, pure => 1); -my $frames = h2_read($sess, all => [ +my $s = Test::Nginx::HTTP2->new(8080, pure => 1); +my $frames = $s->read(all => [ { type => 'WINDOW_UPDATE' }, { type => 'SETTINGS'} ]); @@ -204,10 +204,10 @@ ok($frame, 'SETTINGS frame'); is($frame->{flags}, 0, 'SETTINGS flags'); is($frame->{sid}, 0, 'SETTINGS stream'); -h2_settings($sess, 1); -h2_settings($sess, 0); +$s->h2_settings(1); +$s->h2_settings(0); -$frames = h2_read($sess, all => [{ type => 'SETTINGS' }]); +$frames = $s->read(all => [{ type => 'SETTINGS' }]); ($frame) = grep { $_->{type} eq 'SETTINGS' } @$frames; ok($frame, 'SETTINGS frame ack'); @@ -215,8 +215,8 @@ is($frame->{flags}, 1, 'SETTINGS flags a # PING -h2_ping($sess, 'SEE-THIS'); -$frames = h2_read($sess, all => [{ type => 'PING' }]); +$s->h2_ping('SEE-THIS'); +$frames = $s->read(all => [{ type => 'PING' }]); ($frame) = grep { $_->{type} eq "PING" } @$frames; ok($frame, 'PING frame'); @@ -229,29 +229,29 @@ is($frame->{sid}, 0, 'PING stream'); SKIP: { skip 'long tests', 6 unless $ENV{TEST_NGINX_UNSAFE}; -push my @sess, new_session(8089, pure => 1); -push @sess, new_session(8089, pure => 1); -h2_ping($sess[-1], 'SEE-THIS'); -push @sess, new_session(8090, pure => 1); -push @sess, new_session(8090, pure => 1); -h2_ping($sess[-1], 'SEE-THIS'); +push my @s, Test::Nginx::HTTP2->new(8089, pure => 1); +push @s, Test::Nginx::HTTP2->new(8089, pure => 1); +$s[-1]->h2_ping('SEE-THIS'); +push @s, Test::Nginx::HTTP2->new(8090, pure => 1); +push @s, Test::Nginx::HTTP2->new(8090, pure => 1); +$s[-1]->h2_ping('SEE-THIS'); select undef, undef, undef, 2.1; -$frames = h2_read(shift @sess, all => [{ type => "GOAWAY" }]); +$frames = (shift @s)->read(all => [{ type => "GOAWAY" }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'recv timeout - new connection GOAWAY'); is($frame->{code}, 1, 'recv timeout - new connection code'); -$frames = h2_read(shift @sess, all => [{ type => "GOAWAY" }]); +$frames = (shift @s)->read(all => [{ type => "GOAWAY" }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; is($frame, undef, 'recv timeout - idle connection GOAWAY'); -$frames = h2_read(shift @sess, all => [{ type => "GOAWAY" }]); +$frames = (shift @s)->read(all => [{ type => "GOAWAY" }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; is($frame, undef, 'idle timeout - new connection GOAWAY'); -$frames = h2_read(shift @sess, all => [{ type => "GOAWAY" }]); +$frames = (shift @s)->read(all => [{ type => "GOAWAY" }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'idle timeout - idle connection GOAWAY'); is($frame->{code}, 0, 'idle timeout - idle connection code'); @@ -260,17 +260,17 @@ is($frame->{code}, 0, 'idle timeout - id # GOAWAY -h2_goaway(new_session(), 0, 0, 5); -h2_goaway(new_session(), 0, 0, 5, 'foobar'); -h2_goaway(new_session(), 0, 0, 5, 'foobar', split => [ 8, 8, 4 ]); +Test::Nginx::HTTP2->new()->h2_goaway(0, 0, 5); +Test::Nginx::HTTP2->new()->h2_goaway(0, 0, 5, 'foobar'); +Test::Nginx::HTTP2->new()->h2_goaway(0, 0, 5, 'foobar', split => [ 8, 8, 4 ]); -$sess = new_session(); -h2_goaway($sess, 0, 0, 5); -h2_goaway($sess, 0, 0, 5); +$s = Test::Nginx::HTTP2->new(); +$s->h2_goaway(0, 0, 5); +$s->h2_goaway(0, 0, 5); -$sess = new_session(); -h2_goaway($sess, 0, 0, 5, 'foobar', len => 0); -$frames = h2_read($sess, all => [{ type => "GOAWAY" }]); +$s = Test::Nginx::HTTP2->new(); +$s->h2_goaway(0, 0, 5, 'foobar', len => 0); +$frames = $s->read(all => [{ type => "GOAWAY" }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'GOAWAY invalid length - GOAWAY frame'); @@ -283,9 +283,9 @@ is($frame->{code}, 6, 'GOAWAY invalid le TODO: { local $TODO = 'not yet'; -$sess = new_session(); -h2_goaway($sess, 1, 0, 5, 'foobar'); -$frames = h2_read($sess, all => [{ type => "GOAWAY" }], wait => 0.5); +$s = Test::Nginx::HTTP2->new(); +$s->h2_goaway(1, 0, 5, 'foobar'); +$frames = $s->read(all => [{ type => "GOAWAY" }], wait => 0.5); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'GOAWAY invalid stream - GOAWAY frame'); @@ -296,9 +296,9 @@ is($frame->{code}, 1, 'GOAWAY invalid st # client-initiated PUSH_PROMISE, just to ensure nothing went wrong # N.B. other implementation returns zero code, which is not anyhow regulated -$sess = new_session(); -raw_write($sess->{socket}, pack("x2C2xN", 4, 0x5, 1)); -$frames = h2_read($sess, all => [{ type => "GOAWAY" }]); +$s = Test::Nginx::HTTP2->new(); +syswrite($s->{socket}, pack("x2C2xN", 4, 0x5, 1)); +$frames = $s->read(all => [{ type => "GOAWAY" }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'client-initiated PUSH_PROMISE - GOAWAY frame'); @@ -306,9 +306,9 @@ is($frame->{code}, 1, 'client-initiated # GET -$sess = new_session(); -my $sid = new_stream($sess); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +my $sid = $s->new_stream(); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; ok($frame, 'HEADERS frame'); @@ -323,8 +323,8 @@ is($frame->{data}, 'body', 'DATA payload # GET in the new stream on same connection -$sid = new_stream($sess); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$sid = $s->new_stream(); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{sid}, $sid, 'HEADERS stream 2'); @@ -339,9 +339,9 @@ is($frame->{data}, 'body', 'DATA payload # HEAD -$sess = new_session(); -$sid = new_stream($sess, { method => 'HEAD' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ method => 'HEAD' }); +$frames = $s->read(all => [{ sid => $sid, fin => 0x4 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{sid}, $sid, 'HEAD - HEADERS'); @@ -353,14 +353,14 @@ is($frame, undef, 'HEAD - no body'); # range filter -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t1.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'range', value => 'bytes=10-19', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 206, 'range - HEADERS status'); @@ -371,9 +371,9 @@ is($frame->{data}, '002XXXX000', 'range # http2_chunk_size=1 -$sess = new_session(); -$sid = new_stream($sess, { path => '/chunk_size' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/chunk_size' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my @data = grep { $_->{type} eq "DATA" } @$frames; is(@data, 4, 'chunk_size frames'); @@ -382,17 +382,17 @@ is(join(' ', map { $_->{flags} } @data), # CONTINUATION -$sess = new_session(); -$sid = new_stream($sess, { continuation => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ continuation => 1, headers => [ { name => ':method', value => 'HEAD', mode => 1 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }]}); -h2_continue($sess, $sid, { continuation => 1, headers => [ +$s->h2_continue($sid, { continuation => 1, headers => [ { name => 'x-foo', value => 'X-Bar', mode => 2 }]}); -h2_continue($sess, $sid, { headers => [ +$s->h2_continue($sid, { headers => [ { name => 'referer', value => 'foo', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame, undef, 'CONTINUATION - fragment 1'); @@ -403,22 +403,22 @@ is($frame->{headers}->{'x-referer'}, 'fo # CONTINUATION - in the middle of request header field -$sess = new_session(); -$sid = new_stream($sess, { continuation => [ 2, 4, 1, 5 ], headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ continuation => [ 2, 4, 1, 5 ], headers => [ { name => ':method', value => 'HEAD', mode => 1 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'CONTINUATION - in header field'); # CONTINUATION on a closed stream -h2_continue($sess, 1, { headers => [ +$s->h2_continue(1, { headers => [ { name => 'x-foo', value => 'X-Bar', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => 1, fin => 1 }]); +$frames = $s->read(all => [{ sid => 1, fin => 1 }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; is($frame->{type}, 'GOAWAY', 'GOAWAY - CONTINUATION closed stream'); @@ -426,23 +426,23 @@ is($frame->{code}, 1, 'GOAWAY - CONTINUA # frame padding -$sess = new_session(); -$sid = new_stream($sess, { padding => 42, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ padding => 42, headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'padding - HEADERS status'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'padding - next stream'); @@ -452,14 +452,14 @@ is($frame->{headers}->{':status'}, 200, TODO: { local $TODO = 'not yet' unless $t->has_version('1.9.11'); -$sess = new_session(); -$sid = new_stream($sess, { padding => 42, continuation => [ 2, 4, 1, 5 ], +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ padding => 42, continuation => [ 2, 4, 1, 5 ], headers => [ { name => ':method', value => 'GET', mode => 1 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'padding - CONTINUATION'); @@ -468,9 +468,9 @@ is($frame->{headers}->{':status'}, 200, # internal redirect -$sess = new_session(); -$sid = new_stream($sess, { path => '/redirect' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/redirect' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 405, 'redirect - HEADERS'); @@ -481,9 +481,9 @@ is($frame->{data}, 'body', 'redirect - D # return 301 with absolute URI -$sess = new_session(); -$sid = new_stream($sess, { path => '/return301_absolute' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/return301_absolute' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 301, 'return 301 absolute - status'); @@ -491,9 +491,9 @@ is($frame->{headers}->{'location'}, 'tex # return 301 with relative URI -$sess = new_session(); -$sid = new_stream($sess, { path => '/return301_relative' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/return301_relative' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 301, 'return 301 relative - status'); @@ -502,13 +502,13 @@ is($frame->{headers}->{'location'}, 'htt # return 301 with relative URI and ':authority' request header field -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/return301_relative', mode => 2 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 301, @@ -518,13 +518,13 @@ is($frame->{headers}->{'location'}, 'htt # return 301 with relative URI and 'host' request header field -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/return301_relative', mode => 2 }, { name => 'host', value => 'localhost', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 301, @@ -534,13 +534,13 @@ is($frame->{headers}->{'location'}, 'htt # virtual host -$sess = new_session(8085); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8085); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => 'host', value => 'localhost', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -549,12 +549,12 @@ is($frame->{headers}->{':status'}, 200, ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'first', 'virtual host - host - DATA'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -565,12 +565,12 @@ is($frame->{data}, 'first', 'virtual hos # virtual host - second -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => 'host', value => 'localhost2', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -579,12 +579,12 @@ is($frame->{headers}->{':status'}, 200, ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'second', 'virtual host 2 - host - DATA'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost2', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -595,14 +595,14 @@ is($frame->{data}, 'second', 'virtual ho # gzip tests for internal nginx version -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/gzip.html' }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'accept-encoding', value => 'gzip' }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'content-encoding'}, 'gzip', 'gzip - encoding'); @@ -613,9 +613,9 @@ gunzip_like($frame->{data}, qr/^SEE-THIS # charset -$sess = new_session(); -$sid = new_stream($sess, { path => '/charset' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/charset' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'content-type'}, 'text/plain; charset=utf-8', 'charset'); @@ -626,10 +626,10 @@ is($frame->{headers}->{'content-type'}, TODO: { local $TODO = 'not yet' unless $t->has_version('1.9.12'); -$sess = new_session(8093); -$sid = new_stream($sess, { path => '/t2.html', split => [35], +$s = Test::Nginx::HTTP2->new(8093); +$sid = $s->new_stream({ path => '/t2.html', split => [35], split_delay => 2.1 }); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); ($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; ok($frame, 'client header timeout'); @@ -637,8 +637,8 @@ is($frame->{code}, 1, 'client header tim } -h2_ping($sess, 'SEE-THIS'); -$frames = h2_read($sess, all => [{ type => 'PING' }]); +$s->h2_ping('SEE-THIS'); +$frames = $s->read(all => [{ type => 'PING' }]); ($frame) = grep { $_->{type} eq "PING" && $_->{flags} & 0x1 } @$frames; ok($frame, 'client header timeout - PING'); @@ -648,10 +648,10 @@ ok($frame, 'client header timeout - PING TODO: { local $TODO = 'not yet' unless $t->has_version('1.9.12'); -$sess = new_session(8093); -$sid = new_stream($sess, { path => '/proxy/t2.html', body_more => 1 }); -h2_body($sess, 'TEST', { split => [10], split_delay => 2.1 }); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$s = Test::Nginx::HTTP2->new(8093); +$sid = $s->new_stream({ path => '/proxy/t2.html', body_more => 1 }); +$s->h2_body('TEST', { split => [10], split_delay => 2.1 }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); ($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; ok($frame, 'client body timeout'); @@ -659,8 +659,8 @@ is($frame->{code}, 1, 'client body timeo } -h2_ping($sess, 'SEE-THIS'); -$frames = h2_read($sess, all => [{ type => 'PING' }]); +$s->h2_ping('SEE-THIS'); +$frames = $s->read(all => [{ type => 'PING' }]); ($frame) = grep { $_->{type} eq "PING" && $_->{flags} & 0x1 } @$frames; ok($frame, 'client body timeout - PING'); @@ -668,20 +668,20 @@ ok($frame, 'client body timeout - PING') # proxied request with logging pristine request header field (e.g., referer) -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET' }, { name => ':scheme', value => 'http' }, { name => ':path', value => '/proxy2/' }, { name => ':authority', value => 'localhost' }, { name => 'referer', value => 'foo' }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'proxy with logging request headers'); -$sid = new_stream($sess); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$sid = $s->new_stream(); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; ok($frame->{headers}, 'proxy with logging request headers - next'); @@ -693,9 +693,9 @@ ok($frame->{headers}, 'proxy with loggin # created with an initial flow-control window size of 65,535 octets. # The connection flow-control window is also 65,535 octets. -$sess = new_session(); -$sid = new_stream($sess, { path => '/t1.html' }); -$frames = h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/t1.html' }); +$frames = $s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); # with the default http2_chunk_size, data is divided into 8 data frames @@ -704,18 +704,18 @@ my $lengths = join ' ', map { $_->{lengt is($lengths, '8192 8192 8192 8192 8192 8192 8192 8191', 'iws - stream blocked on initial window size'); -h2_ping($sess, 'SEE-THIS'); -$frames = h2_read($sess, all => [{ type => 'PING' }]); +$s->h2_ping('SEE-THIS'); +$frames = $s->read(all => [{ type => 'PING' }]); ($frame) = grep { $_->{type} eq "PING" && $_->{flags} & 0x1 } @$frames; ok($frame, 'iws - PING not blocked'); -h2_window($sess, 2**16, $sid); -$frames = h2_read($sess, wait => 0.2); +$s->h2_window(2**16, $sid); +$frames = $s->read(wait => 0.2); is(@$frames, 0, 'iws - updated stream window'); -h2_window($sess, 2**16); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_window(2**16); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); @data = grep { $_->{type} eq "DATA" } @$frames; my $sum = eval join '+', map { $_->{length} } @data; @@ -729,12 +729,12 @@ is($sum, 81, 'iws - updated connection w # frame that forms part of the connection preface. The connection # flow-control window can only be changed using WINDOW_UPDATE frames. -$sess = new_session(); -h2_settings($sess, 0, 0x4 => 2**17); -h2_window($sess, 2**17); +$s = Test::Nginx::HTTP2->new(); +$s->h2_settings(0, 0x4 => 2**17); +$s->h2_window(2**17); -$sid = new_stream($sess, { path => '/t1.html' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$sid = $s->new_stream({ path => '/t1.html' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); @data = grep { $_->{type} eq "DATA" } @$frames; $sum = eval join '+', map { $_->{length} } @data; @@ -749,15 +749,15 @@ is($sum, 2**16 + 80, 'iws - increased'); # controlled frames until it receives WINDOW_UPDATE frames that cause # the flow-control window to become positive. -$sess = new_session(); -$sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -h2_window($sess, 1); -h2_settings($sess, 0, 0x4 => 42); -h2_window($sess, 1024, $sid); +$s->h2_window(1); +$s->h2_settings(0, 0x4 => 42); +$s->h2_window(1024, $sid); -$frames = h2_read($sess, all => [{ type => 'SETTINGS' }]); +$frames = $s->read(all => [{ type => 'SETTINGS' }]); ($frame) = grep { $_->{type} eq 'SETTINGS' } @$frames; ok($frame, 'negative window - SETTINGS frame ack'); @@ -768,14 +768,14 @@ is($frame, undef, 'negative window - no # predefined window size, minus new iws settings, minus window update -h2_window($sess, 2**16 - 1 - 42 - 1024, $sid); +$s->h2_window(2**16 - 1 - 42 - 1024, $sid); -$frames = h2_read($sess, wait => 0.2); +$frames = $s->read(wait => 0.2); is(@$frames, 0, 'zero window - no data'); -h2_window($sess, 1, $sid); +$s->h2_window(1, $sid); -$frames = h2_read($sess, all => [{ sid => $sid, length => 1 }]); +$frames = $s->read(all => [{ sid => $sid, length => 1 }]); is(@$frames, 1, 'positive window'); SKIP: { @@ -788,13 +788,13 @@ is(@$frames[0]->{length}, 1, 'positive w # ask write handler in sending large response -$sid = new_stream($sess, { path => '/tbig.html' }); +$sid = $s->new_stream({ path => '/tbig.html' }); -h2_window($sess, 2**30, $sid); -h2_window($sess, 2**30); +$s->h2_window(2**30, $sid); +$s->h2_window(2**30); sleep 1; -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'large response - HEADERS'); @@ -817,8 +817,8 @@ skip 'tolerant operating system', 1 unle TODO: { local $TODO = 'not yet'; -$sid = new_stream($sess); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$sid = $s->new_stream(); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'new stream after large response'); @@ -829,79 +829,79 @@ is($frame->{headers}->{':status'}, 200, # write event send timeout -$sess = new_session(8091); -$sid = new_stream($sess, { path => '/tbig.html' }); -h2_window($sess, 2**30, $sid); -h2_window($sess, 2**30); +$s = Test::Nginx::HTTP2->new(8091); +$sid = $s->new_stream({ path => '/tbig.html' }); +$s->h2_window(2**30, $sid); +$s->h2_window(2**30); select undef, undef, undef, 2.1; -h2_ping($sess, 'SEE-THIS'); +$s->h2_ping('SEE-THIS'); -$frames = h2_read($sess, all => [{ type => 'PING' }]); +$frames = $s->read(all => [{ type => 'PING' }]); ok(!grep ({ $_->{type} eq "PING" } @$frames), 'large response - send timeout'); # stream with large response queued on write - RST_STREAM handling -$sess = new_session(); -$sid = new_stream($sess, { path => '/tbig.html' }); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/tbig.html' }); -h2_window($sess, 2**30, $sid); -h2_window($sess, 2**30); +$s->h2_window(2**30, $sid); +$s->h2_window(2**30); select undef, undef, undef, 0.4; -h2_rst($sess, $sid, 8); -h2_read($sess, all => [{ sid => $sid, fin => 1 }], wait => 0.2); +$s->h2_rst($sid, 8); +$s->read(all => [{ sid => $sid, fin => 1 }], wait => 0.2); -$sid = new_stream($sess); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$sid = $s->new_stream(); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{sid}, 3, 'large response - queued with RST_STREAM'); # SETTINGS_MAX_FRAME_SIZE -$sess = new_session(); -$sid = new_stream($sess, { path => '/frame_size' }); -h2_window($sess, 2**18, 1); -h2_window($sess, 2**18); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/frame_size' }); +$s->h2_window(2**18, 1); +$s->h2_window(2**18); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); @data = grep { $_->{type} eq "DATA" } @$frames; is($data[0]->{length}, 2**14, 'max frame size - default'); -$sess = new_session(); -h2_settings($sess, 0, 0x5 => 2**15); -$sid = new_stream($sess, { path => '/frame_size' }); -h2_window($sess, 2**18, 1); -h2_window($sess, 2**18); +$s = Test::Nginx::HTTP2->new(); +$s->h2_settings(0, 0x5 => 2**15); +$sid = $s->new_stream({ path => '/frame_size' }); +$s->h2_window(2**18, 1); +$s->h2_window(2**18); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); @data = grep { $_->{type} eq "DATA" } @$frames; is($data[0]->{length}, 2**15, 'max frame size - custom'); # stream multiplexing + WINDOW_UPDATE -$sess = new_session(); -$sid = new_stream($sess, { path => '/t1.html' }); -$frames = h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/t1.html' }); +$frames = $s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); @data = grep { $_->{type} eq "DATA" } @$frames; $sum = eval join '+', map { $_->{length} } @data; is($sum, 2**16 - 1, 'multiple - stream1 data'); -my $sid2 = new_stream($sess, { path => '/t1.html' }); -$frames = h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +my $sid2 = $s->new_stream({ path => '/t1.html' }); +$frames = $s->read(all => [{ sid => $sid2, fin => 0x4 }]); @data = grep { $_->{type} eq "DATA" } @$frames; is(@data, 0, 'multiple - stream2 no data'); -h2_window($sess, 2**17, $sid); -h2_window($sess, 2**17, $sid2); -h2_window($sess, 2**17); +$s->h2_window(2**17, $sid); +$s->h2_window(2**17, $sid2); +$s->h2_window(2**17); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 } ]); @@ -916,22 +916,22 @@ is($sum, 2**16 + 80, 'multiple - stream2 # http2_max_concurrent_streams -$sess = new_session(8086, pure => 1); -$frames = h2_read($sess, all => [{ type => 'SETTINGS' }]); +$s = Test::Nginx::HTTP2->new(8086, pure => 1); +$frames = $s->read(all => [{ type => 'SETTINGS' }]); ($frame) = grep { $_->{type} eq 'SETTINGS' } @$frames; is($frame->{3}, 1, 'http2_max_concurrent_streams SETTINGS'); -h2_window($sess, 2**18); +$s->h2_window(2**18); -$sid = new_stream($sess, { path => '/t1.html' }); -$frames = h2_read($sess, all => [{ sid => $sid, length => 2 ** 16 - 1 }]); +$sid = $s->new_stream({ path => '/t1.html' }); +$frames = $s->read(all => [{ sid => $sid, length => 2 ** 16 - 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid } @$frames; is($frame->{headers}->{':status'}, 200, 'http2_max_concurrent_streams'); -$sid2 = new_stream($sess, { path => '/t1.html' }); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$sid2 = $s->new_stream({ path => '/t1.html' }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid2 } @$frames; isnt($frame->{headers}->{':status'}, 200, 'http2_max_concurrent_streams 2'); @@ -944,38 +944,38 @@ is($frame->{code}, 7, 'http2_max_concurr # properly skip header field that's not/never indexed from discarded streams -$sid2 = new_stream($sess, { headers => [ +$sid2 = $s->new_stream({ headers => [ { name => ':method', value => 'GET' }, { name => ':scheme', value => 'http' }, { name => ':path', value => '/', mode => 6 }, { name => ':authority', value => 'localhost' }, { name => 'x-foo', value => 'Foo', mode => 2 }]}); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); # also if split across writes -$sid2 = new_stream($sess, { split => [ 22 ], headers => [ +$sid2 = $s->new_stream({ split => [ 22 ], headers => [ { name => ':method', value => 'GET' }, { name => ':scheme', value => 'http' }, { name => ':path', value => '/', mode => 6 }, { name => ':authority', value => 'localhost' }, { name => 'x-bar', value => 'Bar', mode => 2 }]}); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); # also if split across frames -$sid2 = new_stream($sess, { continuation => [ 17 ], headers => [ +$sid2 = $s->new_stream({ continuation => [ 17 ], headers => [ { name => ':method', value => 'GET' }, { name => ':scheme', value => 'http' }, { name => ':path', value => '/', mode => 6 }, { name => ':authority', value => 'localhost' }, { name => 'x-baz', value => 'Baz', mode => 2 }]}); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); -h2_window($sess, 2**16, $sid); -h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_window(2**16, $sid); +$s->read(all => [{ sid => $sid, fin => 1 }]); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET' }, { name => ':scheme', value => 'http' }, { name => ':path', value => '/t2.html' }, @@ -984,7 +984,7 @@ h2_read($sess, all => [{ sid => $sid, fi { name => 'x-foo', value => 'Foo', mode => 0 }, { name => 'x-bar', value => 'Bar', mode => 0 }, { name => 'x-baz', value => 'Baz', mode => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid } @$frames; is($frame->{headers}->{':status'}, 200, 'http2_max_concurrent_streams 3'); @@ -994,16 +994,16 @@ is($frame->{headers}->{':status'}, 200, # invalid connection preface -$sess = new_session(8080, preface => 'x' x 16, pure => 1); -$frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); +$s = Test::Nginx::HTTP2->new(8080, preface => 'x' x 16, pure => 1); +$frames = $s->read(all => [{ type => 'GOAWAY' }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'invalid preface - GOAWAY frame'); is($frame->{code}, 1, 'invalid preface - error code'); -$sess = new_session(8080, preface => 'PRI * HTTP/2.0' . CRLF . CRLF . 'x' x 8, - pure => 1); -$frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); +my $preface = 'PRI * HTTP/2.0' . CRLF . CRLF . 'x' x 8; +$s = Test::Nginx::HTTP2->new(8080, preface => $preface, pure => 1); +$frames = $s->read(all => [{ type => 'GOAWAY' }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'invalid preface 2 - GOAWAY frame'); @@ -1011,9 +1011,9 @@ is($frame->{code}, 1, 'invalid preface 2 # GOAWAY on SYN_STREAM with even StreamID -$sess = new_session(); -new_stream($sess, { path => '/' }, 2); -$frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); +$s = Test::Nginx::HTTP2->new(); +$s->new_stream({ path => '/' }, 2); +$frames = $s->read(all => [{ type => 'GOAWAY' }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'even stream - GOAWAY frame'); @@ -1026,12 +1026,12 @@ is($frame->{last_sid}, 0, 'even stream - # The first use of a new stream identifier implicitly closes all # streams in the "idle" state <..> with a lower-valued stream identifier. -$sess = new_session(); -$sid = new_stream($sess, { path => '/' }, 3); -h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/' }, 3); +$s->read(all => [{ sid => $sid, fin => 1 }]); -$sid2 = new_stream($sess, { path => '/' }, 1); -$frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); +$sid2 = $s->new_stream({ path => '/' }, 1); +$frames = $s->read(all => [{ type => 'GOAWAY' }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'backward stream - GOAWAY frame'); @@ -1040,12 +1040,12 @@ is($frame->{last_sid}, $sid, 'backward s # GOAWAY on the second SYN_STREAM with same StreamID -$sess = new_session(); -$sid = new_stream($sess, { path => '/' }); -h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/' }); +$s->read(all => [{ sid => $sid, fin => 1 }]); -$sid2 = new_stream($sess, { path => '/' }, $sid); -$frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); +$sid2 = $s->new_stream({ path => '/' }, $sid); +$frames = $s->read(all => [{ type => 'GOAWAY' }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'dup stream - GOAWAY frame'); @@ -1054,52 +1054,52 @@ is($frame->{last_sid}, $sid, 'dup stream # aborted stream with zero HEADERS payload followed by client connection close -new_stream(new_session(), { split => [ 9 ], abort => 1 }); +Test::Nginx::HTTP2->new()->new_stream({ split => [ 9 ], abort => 1 }); # unknown frame type -$sess = new_session(); -h2_unknown($sess, 'payload'); -h2_ping($sess, 'SEE-THIS'); -$frames = h2_read($sess, all => [{ type => 'PING' }]); +$s = Test::Nginx::HTTP2->new(); +$s->h2_unknown('payload'); +$s->h2_ping('SEE-THIS'); +$frames = $s->read(all => [{ type => 'PING' }]); ($frame) = grep { $_->{type} eq "PING" } @$frames; is($frame->{value}, 'SEE-THIS', 'unknown frame type'); # GOAWAY - force closing a connection by server -$sid = new_stream($sess); -h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$sid = $s->new_stream(); +$s->read(all => [{ sid => $sid, fin => 1 }]); # graceful shutdown with stream waiting on HEADERS payload -my $grace = new_session(8089); -new_stream($grace, { split => [ 9 ], abort => 1 }); +my $grace = Test::Nginx::HTTP2->new(8089); +$grace->new_stream({ split => [ 9 ], abort => 1 }); # graceful shutdown with stream waiting on WINDOW_UPDATE -my $grace2 = new_session(8089); -$sid = new_stream($grace2, { path => '/t1.html' }); -h2_read($grace2, all => [{ sid => $sid, length => 2**16 - 1 }]); +my $grace2 = Test::Nginx::HTTP2->new(8089); +$sid = $grace2->new_stream({ path => '/t1.html' }); +$grace2->read(all => [{ sid => $sid, length => 2**16 - 1 }]); # graceful shutdown waiting on incomplete request body DATA frames -my $grace3 = new_session(8090); -$sid = new_stream($grace3, { path => '/proxy2/t2.html', body_more => 1 }); -h2_body($grace3, 'TEST', { body_more => 1 }); +my $grace3 = Test::Nginx::HTTP2->new(8090); +$sid = $grace3->new_stream({ path => '/proxy2/t2.html', body_more => 1 }); +$grace3->h2_body('TEST', { body_more => 1 }); # partial request body data frame with connection close after body timeout -my $grace4 = new_session(8093); -$sid = new_stream($grace4, { path => '/proxy/t2.html', body_more => 1 }); -h2_body($grace4, 'TEST', { split => [ 12 ], abort => 1 }); +my $grace4 = Test::Nginx::HTTP2->new(8093); +$sid = $grace4->new_stream({ path => '/proxy/t2.html', body_more => 1 }); +$grace4->h2_body('TEST', { split => [ 12 ], abort => 1 }); select undef, undef, undef, 1.1; undef $grace4; $t->stop(); -$frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); +$frames = $s->read(all => [{ type => 'GOAWAY' }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'GOAWAY on connection close'); diff --git a/h2_cache.t b/h2_cache.t --- a/h2_cache.t +++ b/h2_cache.t @@ -16,7 +16,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame /; +use Test::Nginx::HTTP2; ############################################################################### @@ -66,9 +66,9 @@ EOF # simple proxy cache test -my $sess = new_session(); -my $sid = new_stream($sess, { path => '/cache/t.html' }); -my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +my $s = Test::Nginx::HTTP2->new(); +my $sid = $s->new_stream({ path => '/cache/t.html' }); +my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, '200', 'proxy cache'); @@ -81,13 +81,13 @@ is($frame->{data}, 'SEE-THIS', 'proxy ca $t->write_file('t.html', 'NOOP'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/cache/t.html' }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'if-none-match', value => $etag }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 304, 'proxy cache conditional'); @@ -96,26 +96,26 @@ is($frame->{headers}->{':status'}, 304, # request body with cached response -$sid = new_stream($sess, { path => '/cache/t.html', body_more => 1 }); -h2_body($sess, 'TEST'); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$sid = $s->new_stream({ path => '/cache/t.html', body_more => 1 }); +$s->h2_body('TEST'); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'proxy cache - request body'); -h2_ping($sess, 'SEE-THIS'); -$frames = h2_read($sess, all => [{ type => 'PING' }]); +$s->h2_ping('SEE-THIS'); +$frames = $s->read(all => [{ type => 'PING' }]); ($frame) = grep { $_->{type} eq "PING" && $_->{flags} & 0x1 } @$frames; ok($frame, 'proxy cache - request body - next'); # HEADERS could be received with fin, followed by DATA -$sess = new_session(); -$sid = new_stream($sess, { path => '/cache/t.html?1', method => 'HEAD' }); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/cache/t.html?1', method => 'HEAD' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }], wait => 0.2); -push @$frames, $_ for @{h2_read($sess, all => [{ sid => $sid }], wait => 0.2)}; +$frames = $s->read(all => [{ sid => $sid, fin => 1 }], wait => 0.2); +push @$frames, $_ for @{$s->read(all => [{ sid => $sid }], wait => 0.2)}; ok(!grep ({ $_->{type} eq "DATA" } @$frames), 'proxy cache HEAD - no body'); # proxy cache - expect no stray empty DATA frame @@ -123,10 +123,10 @@ ok(!grep ({ $_->{type} eq "DATA" } @$fra TODO: { local $TODO = 'not yet'; -$sess = new_session(); -$sid = new_stream($sess, { path => '/cache/t.html?2' }); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/cache/t.html?2' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my @data = grep ({ $_->{type} eq "DATA" } @$frames); is(@data, 1, 'proxy cache write - data frames'); is(join(' ', map { $_->{data} } @data), 'SEE-THIS', 'proxy cache write - data'); @@ -136,12 +136,12 @@ is(join(' ', map { $_->{flags} } @data), # HEAD on empty cache with proxy_buffering off -$sess = new_session(); -$sid = new_stream($sess, +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream( { path => '/proxy_buffering_off/t.html?1', method => 'HEAD' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); -push @$frames, $_ for @{h2_read($sess, all => [{ sid => $sid }], wait => 0.2)}; +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); +push @$frames, $_ for @{$s->read(all => [{ sid => $sid }], wait => 0.2)}; ok(!grep ({ $_->{type} eq "DATA" } @$frames), 'proxy cache HEAD buffering off - no body'); diff --git a/h2_fastcgi_request_buffering.t b/h2_fastcgi_request_buffering.t --- a/h2_fastcgi_request_buffering.t +++ b/h2_fastcgi_request_buffering.t @@ -16,7 +16,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame :io /; +use Test::Nginx::HTTP2; ############################################################################### @@ -197,9 +197,9 @@ sub get_body { ) or die "Can't create listening socket: $!\n"; - my $sess = new_session(8080); + my $s = Test::Nginx::HTTP2->new(); my $sid = exists $extra{'content-length'} - ? new_stream($sess, { headers => [ + ? $s->new_stream({ headers => [ { name => ':method', value => 'GET' }, { name => ':scheme', value => 'http' }, { name => ':path', value => $url, }, @@ -207,13 +207,13 @@ sub get_body { { name => 'content-length', value => $extra{'content-length'} }], body_more => 1 }) - : new_stream($sess, { path => $url, body_more => 1 }); + : $s->new_stream({ path => $url, body_more => 1 }); $client = $server->accept() or return; log2c("(new connection $client)"); - $f->{headers} = raw_read($client, '', 1, \&log2i); + $f->{headers} = backend_read($client); my $h = fastcgi_read_record(\$f->{headers}); my $version = $h->{version}; @@ -224,13 +224,12 @@ sub get_body { my $len = length($body); my $wait = $extra{wait}; - h2_body($sess, $body, { %extra }); + $s->h2_body($body, { %extra }); $body = ''; for (1 .. 10) { - my $buf = raw_read($client, '', 1, \&log2i, $wait) - or return ''; + my $buf = backend_read($client, $wait) or return ''; while (my $h = fastcgi_read_record(\$buf)) { @@ -260,13 +259,24 @@ EOF $client->close; - my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); + my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; return $frame->{headers}->{':status'}; }; return $f; } +sub backend_read { + my ($s, $timo) = @_; + my $buf = ''; + + if (IO::Select->new($s)->can_read($timo || 3)) { + $s->sysread($buf, 16384) or return; + log2i($buf); + } + return $buf; +} + sub log2i { Test::Nginx::log_core('|| <<', @_); } sub log2o { Test::Nginx::log_core('|| >>', @_); } sub log2c { Test::Nginx::log_core('||', @_); } diff --git a/h2_headers.t b/h2_headers.t --- a/h2_headers.t +++ b/h2_headers.t @@ -17,7 +17,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame /; +use Test::Nginx::HTTP2; ############################################################################### @@ -126,97 +126,97 @@ open STDERR, ">&", \*OLDERR; # 6.1. Indexed Header Field Representation -my $sess = new_session(); -my $sid = new_stream($sess, { headers => [ +my $s = Test::Nginx::HTTP2->new(); +my $sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }]}); -my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'indexed header field'); # 6.2.1. Literal Header Field with Incremental Indexing -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 1, huff => 0 }, { name => ':scheme', value => 'http', mode => 1, huff => 0 }, { name => ':path', value => '/', mode => 1, huff => 0 }, { name => ':authority', value => 'localhost', mode => 1, huff => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal with indexing'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 1, huff => 1 }, { name => ':scheme', value => 'http', mode => 1, huff => 1 }, { name => ':path', value => '/', mode => 1, huff => 1 }, { name => ':authority', value => 'localhost', mode => 1, huff => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal with indexing - huffman'); # 6.2.1. Literal Header Field with Incremental Indexing -- New Name -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 2, huff => 0 }, { name => ':scheme', value => 'http', mode => 2, huff => 0 }, { name => ':path', value => '/', mode => 2, huff => 0 }, { name => ':authority', value => 'localhost', mode => 2, huff => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal with indexing - new'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 2, huff => 1 }, { name => ':scheme', value => 'http', mode => 2, huff => 1 }, { name => ':path', value => '/', mode => 2, huff => 1 }, { name => ':authority', value => 'localhost', mode => 2, huff => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal with indexing - new huffman'); # 6.2.2. Literal Header Field without Indexing -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 3, huff => 0 }, { name => ':scheme', value => 'http', mode => 3, huff => 0 }, { name => ':path', value => '/', mode => 3, huff => 0 }, { name => ':authority', value => 'localhost', mode => 3, huff => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal without indexing'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 3, huff => 1 }, { name => ':scheme', value => 'http', mode => 3, huff => 1 }, { name => ':path', value => '/', mode => 3, huff => 1 }, { name => ':authority', value => 'localhost', mode => 3, huff => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal without indexing - huffman'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 3, huff => 0 }, { name => ':scheme', value => 'http', mode => 3, huff => 0 }, { name => ':path', value => '/', mode => 3, huff => 0 }, { name => ':authority', value => 'localhost', mode => 3, huff => 0 }, { name => 'referer', value => 'foo', mode => 3, huff => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -226,24 +226,24 @@ is($frame->{headers}->{'x-referer'}, 'fo # 6.2.2. Literal Header Field without Indexing -- New Name -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 4, huff => 0 }, { name => ':scheme', value => 'http', mode => 4, huff => 0 }, { name => ':path', value => '/', mode => 4, huff => 0 }, { name => ':authority', value => 'localhost', mode => 4, huff => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal without indexing - new'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 4, huff => 1 }, { name => ':scheme', value => 'http', mode => 4, huff => 1 }, { name => ':path', value => '/', mode => 4, huff => 1 }, { name => ':authority', value => 'localhost', mode => 4, huff => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -251,36 +251,36 @@ is($frame->{headers}->{':status'}, 200, # 6.2.3. Literal Header Field Never Indexed -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 5, huff => 0 }, { name => ':scheme', value => 'http', mode => 5, huff => 0 }, { name => ':path', value => '/', mode => 5, huff => 0 }, { name => ':authority', value => 'localhost', mode => 5, huff => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal never indexed'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 5, huff => 1 }, { name => ':scheme', value => 'http', mode => 5, huff => 1 }, { name => ':path', value => '/', mode => 5, huff => 1 }, { name => ':authority', value => 'localhost', mode => 5, huff => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal never indexed - huffman'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 5, huff => 0 }, { name => ':scheme', value => 'http', mode => 5, huff => 0 }, { name => ':path', value => '/', mode => 5, huff => 0 }, { name => ':authority', value => 'localhost', mode => 5, huff => 0 }, { name => 'referer', value => 'foo', mode => 5, huff => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -290,87 +290,87 @@ is($frame->{headers}->{'x-referer'}, 'fo # 6.2.3. Literal Header Field Never Indexed -- New Name -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 6, huff => 0 }, { name => ':scheme', value => 'http', mode => 6, huff => 0 }, { name => ':path', value => '/', mode => 6, huff => 0 }, { name => ':authority', value => 'localhost', mode => 6, huff => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal never indexed - new'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 6, huff => 1 }, { name => ':scheme', value => 'http', mode => 6, huff => 1 }, { name => ':path', value => '/', mode => 6, huff => 1 }, { name => ':authority', value => 'localhost', mode => 6, huff => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'literal never indexed - new huffman'); # reuse literal with multibyte indexing -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'referer', value => 'foo', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-referer'}, 'foo', 'value with indexing - new'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 0 }, { name => 'referer', value => 'foo', mode => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-referer'}, 'foo', 'value with indexing - indexed'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'x-foo', value => 'X-Bar', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-sent-foo'}, 'X-Bar', 'name with indexing - new'); # reuse literal with multibyte indexing - reused name -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 0 }, { name => 'x-foo', value => 'X-Bar', mode => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-sent-foo'}, 'X-Bar', 'name with indexing - indexed'); # reuse literal with multibyte indexing - reused name only -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 0 }, { name => 'x-foo', value => 'X-Baz', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-sent-foo'}, 'X-Baz', @@ -378,30 +378,30 @@ is($frame->{headers}->{'x-sent-foo'}, 'X # response header field with characters not suitable for huffman encoding -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'x-foo', value => '{{{{{', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-sent-foo'}, '{{{{{', 'rare chars'); -like($sess->{headers}, qr/\Q{{{{{/, 'rare chars - no huffman encoding'); +like($s->{headers}, qr/\Q{{{{{/, 'rare chars - no huffman encoding'); # response header field with huffman encoding # NB: implementation detail, not obligated -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'x-foo', value => 'aaaaa', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-sent-foo'}, 'aaaaa', 'well known chars'); @@ -409,7 +409,7 @@ is($frame->{headers}->{'x-sent-foo'}, 'a TODO: { local $TODO = 'not yet' unless $t->has_version('1.9.12'); -unlike($sess->{headers}, qr/aaaaa/, 'well known chars - huffman encoding'); +unlike($s->{headers}, qr/aaaaa/, 'well known chars - huffman encoding'); } @@ -418,14 +418,14 @@ unlike($sess->{headers}, qr/aaaaa/, 'wel my $field = pack "C*", ((map { 97 } (1 .. 862)), 1 .. 9, 11, 12, 14 .. 255); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'x-foo', value => $field, mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-sent-foo'}, $field, 'all chars'); @@ -433,7 +433,7 @@ is($frame->{headers}->{'x-sent-foo'}, $f TODO: { local $TODO = 'not yet' unless $t->has_version('1.9.12'); -unlike($sess->{headers}, qr/abcde/, 'all chars - huffman encoding'); +unlike($s->{headers}, qr/abcde/, 'all chars - huffman encoding'); } @@ -443,34 +443,34 @@ unlike($sess->{headers}, qr/abcde/, 'all # by maintaining dynamic table space only for index 0 # 'x-foo' has index 0, and 'referer' has index 1 -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'referer', value => 'foo', mode => 1 }, { name => 'x-foo', value => 'X-Bar', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); -$sid = new_stream($sess, { table_size => 61, headers => [ +$sid = $s->new_stream({ table_size => 61, headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => 'x-foo', value => 'X-Bar', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; isnt($frame, undef, 'updated table size - remaining index'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'referer', value => 'foo', mode => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame, undef, 'invalid index'); @@ -499,28 +499,28 @@ is($frame->{code}, 9, 'invalid index - G # The index value of 0 is not used. It MUST be treated as a decoding # error if found in an indexed header field representation. -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => '', value => '', mode => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ok($frame, 'zero index - GOAWAY'); is($frame->{code}, 9, 'zero index - GOAWAY COMPRESSION_ERROR'); # invalid table size update -$sess = new_session(); -$sid = new_stream($sess, { table_size => 4097, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ table_size => 4097, headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => 'x-foo', value => 'X-Bar', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'invalid table size - GOAWAY'); @@ -533,15 +533,15 @@ is($frame->{code}, 9, 'invalid table siz # To allow for better compression efficiency, the Cookie header field # MAY be split into separate header fields <..>. -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/cookie', mode => 2 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'cookie', value => 'a=b', mode => 2}, { name => 'cookie', value => 'c=d', mode => 2}]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-cookie-a'}, 'b', @@ -559,15 +559,15 @@ is($frame->{headers}->{'x-cookie'}, 'a=b # before being passed into a non-HTTP/2 context, such as an HTTP/1.1 # connection <..> -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/proxy/cookie', mode => 2 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'cookie', value => 'a=b', mode => 2 }, { name => 'cookie', value => 'c=d', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-sent-cookie'}, 'a=b; c=d', @@ -581,9 +581,9 @@ is($frame->{headers}->{'x-sent-cookie-c' # response header field with multiple values -$sess = new_session(); -$sid = new_stream($sess, { path => '/set-cookie' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/set-cookie' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'set-cookie'}[0], 'a=b', @@ -593,9 +593,9 @@ is($frame->{headers}->{'set-cookie'}[1], # response header field with multiple values from HTTP backend -$sess = new_session(); -$sid = new_stream($sess, { path => '/proxy/set-cookie' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/proxy/set-cookie' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'set-cookie'}[0], 'a=b', @@ -611,10 +611,10 @@ is($frame->{headers}->{'x-uc-c'}, 'd', # put three long header fields (not less than SETTINGS_MAX_FRAME_SIZE/2) # to break header block into separate frames, one such field per frame -$sess = new_session(); -$sid = new_stream($sess, { path => '/continuation?h=' . 'x' x 2**13 }); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/continuation?h=' . 'x' x 2**13 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 0x4 }]); my @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; is(@{$data[-1]->{headers}{'x-longheader'}}, 3, 'response CONTINUATION - headers'); @@ -629,10 +629,10 @@ cmp_ok($data[-1], '<=', 2**14, 'response # same but without response DATA frames -$sess = new_session(); -$sid = new_stream($sess, { path => '/continuation/204?h=' . 'x' x 2**13 }); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/continuation/204?h=' . 'x' x 2**13 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 0x4 }]); @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; is(@{$data[-1]->{headers}{'x-longheader'}}, 3, 'no body CONTINUATION - headers'); @@ -647,10 +647,10 @@ cmp_ok($data[-1], '<=', 2**14, 'no body # response header block is always split by SETTINGS_MAX_FRAME_SIZE -$sess = new_session(); -$sid = new_stream($sess, { path => '/continuation?h=' . 'x' x 2**15 }); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/continuation?h=' . 'x' x 2**15 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 0x4 }]); @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; @data = sort { $a <=> $b } map { $_->{length} } @data; cmp_ok($data[-1], '<=', 2**14, 'response header frames limited'); @@ -660,11 +660,11 @@ cmp_ok($data[-1], '<=', 2**14, 'response TODO: { local $TODO = 'not yet' unless $t->has_version('1.9.7'); -$sess = new_session(8082); -h2_settings($sess, 0, 0x5 => 2**17); +$s = Test::Nginx::HTTP2->new(8082); +$s->h2_settings(0, 0x5 => 2**17); -$sid = new_stream($sess, { path => '/frame_size?h=' . 'x' x 2**15 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); +$sid = $s->new_stream({ path => '/frame_size?h=' . 'x' x 2**15 }); +$frames = $s->read(all => [{ sid => $sid, fin => 0x4 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; ok($frame, 'response header - parts'); @@ -679,9 +679,9 @@ is(length join('', @{$frame->{headers}-> # response header block split and sent in parts -$sess = new_session(8082); -$sid = new_stream($sess, { path => '/continuation?h=' . 'x' x 2**15 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); +$s = Test::Nginx::HTTP2->new(8082); +$sid = $s->new_stream({ path => '/continuation?h=' . 'x' x 2**15 }); +$frames = $s->read(all => [{ sid => $sid, fin => 0x4 }]); @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; my ($lengths) = sort { $b <=> $a } map { $_->{length} } @data; @@ -694,136 +694,136 @@ is(length join('', @{@$frames[-1]->{head # max_field_size - header field name -$sess = new_session(8084); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8084); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname10' x 2 . 'x', value => 'value', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'field name size less'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname10' x 2 . 'x', value => 'value', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'field name size second'); -$sess = new_session(8084); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8084); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname10' x 2 . 'xx', value => 'value', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'field name size equal'); -$sess = new_session(8084); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8084); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname10' x 2 . 'xxx', value => 'value', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; is($frame, undef, 'field name size greater'); # max_field_size - header field value -$sess = new_session(8084); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8084); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'name', value => 'valu5' x 4 . 'x', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'field value size less'); -$sess = new_session(8084); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8084); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'name', value => 'valu5' x 4 . 'xx', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'field value size equal'); -$sess = new_session(8084); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8084); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'name', value => 'valu5' x 4 . 'xxx', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; is($frame, undef, 'field value size greater'); # max_header_size -$sess = new_session(8085); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8085); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname9', value => 'x', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'header size less'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname9', value => 'x', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'header size second'); -$sess = new_session(8085); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8085); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname9', value => 'xx', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'header size equal'); -$sess = new_session(8085); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8085); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname9', value => 'xxx', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; is($frame, undef, 'header size greater'); @@ -831,51 +831,51 @@ is($frame, undef, 'header size greater') # header size is based on (decompressed) header list # two extra 1-byte indices would otherwise fit in max_header_size -$sess = new_session(8085); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(8085); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname9', value => 'x', mode => 2 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'header size new index'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname9', value => 'x', mode => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'DATA' } @$frames; ok($frame, 'header size indexed'); -$sid = new_stream($sess, { headers => [ +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t2.html', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'longname9', value => 'x', mode => 0 }, { name => 'longname9', value => 'x', mode => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq 'GOAWAY' } @$frames; is($frame->{code}, 0xb, 'header size indexed greater'); # HPACK table boundary -$sess = new_session(); -h2_read($sess, all => [{ sid => new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$s->read(all => [{ sid => $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => '', mode => 0 }, { name => 'x' x 2016, value => 'x' x 2048, mode => 2 }]}), fin => 1 }]); -$frames = h2_read($sess, all => [{ sid => new_stream($sess, { headers => [ +$frames = $s->read(all => [{ sid => $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, @@ -885,13 +885,13 @@ h2_read($sess, all => [{ sid => new_stre ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; ok($frame, 'HPACK table boundary'); -h2_read($sess, all => [{ sid => new_stream($sess, { headers => [ +$s->read(all => [{ sid => $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => '', mode => 0 }, { name => 'x' x 33, value => 'x' x 4031, mode => 2 }]}), fin => 1 }]); -$frames = h2_read($sess, all => [{ sid => new_stream($sess, { headers => [ +$frames = $s->read(all => [{ sid => $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, @@ -901,13 +901,13 @@ h2_read($sess, all => [{ sid => new_stre ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; ok($frame, 'HPACK table boundary - header field name'); -h2_read($sess, all => [{ sid => new_stream($sess, { headers => [ +$s->read(all => [{ sid => $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => '', mode => 0 }, { name => 'x', value => 'x' x 64, mode => 2 }]}), fin => 1 }]); -$frames = h2_read($sess, all => [{ sid => new_stream($sess, { headers => [ +$frames = $s->read(all => [{ sid => $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, @@ -923,14 +923,14 @@ ok($frame, 'HPACK table boundary - heade # Any request or response that contains a character not permitted # in a header field value MUST be treated as malformed. -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/proxy2/', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'x-foo', value => "x-bar\r\nreferer:see-this", mode => 2 }]}); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); # 10.3. Intermediary Encapsulation Attacks # An intermediary therefore cannot translate an HTTP/2 request or response @@ -954,15 +954,15 @@ is($frame->{code}, 1, 'newline in reques TODO: { local $TODO = 'not yet' unless $t->has_version('1.9.7'); -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'x_foo', value => "x-bar", mode => 2 }, { name => 'referer', value => "see-this", mode => 1 }]}); -$frames = h2_read($sess, all => [{ type => 'HEADERS' }]); +$frames = $s->read(all => [{ type => 'HEADERS' }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{'x-referer'}, 'see-this', 'after invalid header name'); @@ -974,12 +974,12 @@ is($frame->{headers}->{'x-referer'}, 'se TODO: { local $TODO = 'not yet'; -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => 'localhost', mode => 1 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 400, 'incomplete headers'); @@ -988,21 +988,21 @@ is($frame->{headers}->{':status'}, 400, # empty request header ':authority' -$sess = new_session(); -$sid = new_stream($sess, { headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/', mode => 0 }, { name => ':authority', value => '', mode => 0 }]}); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 400, 'empty authority'); # client sent invalid :path header -$sid = new_stream($sess, { path => 't1.html' }); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$sid = $s->new_stream({ path => 't1.html' }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); ($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; is($frame->{code}, 1, 'invalid path'); diff --git a/h2_limit_conn.t b/h2_limit_conn.t --- a/h2_limit_conn.t +++ b/h2_limit_conn.t @@ -16,7 +16,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame /; +use Test::Nginx::HTTP2; ############################################################################### @@ -55,42 +55,42 @@ EOF ############################################################################### -my $sess = new_session(); -h2_settings($sess, 0, 0x4 => 1); +my $s = Test::Nginx::HTTP2->new(); +$s->h2_settings(0, 0x4 => 1); -my $sid = new_stream($sess, { path => '/t.html' }); -my $frames = h2_read($sess, all => [{ sid => $sid, length => 1 }]); +my $sid = $s->new_stream({ path => '/t.html' }); +my $frames = $s->read(all => [{ sid => $sid, length => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid } @$frames; is($frame->{headers}->{':status'}, 200, 'limit_conn first stream'); -my $sid2 = new_stream($sess, { path => '/t.html' }); -$frames = h2_read($sess, all => [{ sid => $sid2, length => 1 }]); +my $sid2 = $s->new_stream({ path => '/t.html' }); +$frames = $s->read(all => [{ sid => $sid2, length => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid2 } @$frames; is($frame->{headers}->{':status'}, 503, 'limit_conn rejected'); -h2_settings($sess, 0, 0x4 => 2**16); +$s->h2_settings(0, 0x4 => 2**16); -h2_read($sess, all => [ +$s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 } ]); # limit_conn + client's RST_STREAM -$sess = new_session(); -h2_settings($sess, 0, 0x4 => 1); +$s = Test::Nginx::HTTP2->new(); +$s->h2_settings(0, 0x4 => 1); -$sid = new_stream($sess, { path => '/t.html' }); -$frames = h2_read($sess, all => [{ sid => $sid, length => 1 }]); -h2_rst($sess, $sid, 5); +$sid = $s->new_stream({ path => '/t.html' }); +$frames = $s->read(all => [{ sid => $sid, length => 1 }]); +$s->h2_rst($sid, 5); ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid } @$frames; is($frame->{headers}->{':status'}, 200, 'RST_STREAM 1'); -$sid2 = new_stream($sess, { path => '/t.html' }); -$frames = h2_read($sess, all => [{ sid => $sid2, length => 1 }]); +$sid2 = $s->new_stream({ path => '/t.html' }); +$frames = $s->read(all => [{ sid => $sid2, length => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid2 } @$frames; is($frame->{headers}->{':status'}, 200, 'RST_STREAM 2'); diff --git a/h2_limit_req.t b/h2_limit_req.t --- a/h2_limit_req.t +++ b/h2_limit_req.t @@ -16,7 +16,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame /; +use Test::Nginx::HTTP2; ############################################################################### @@ -69,13 +69,13 @@ EOF $t->run(); ############################################################################### - +my $sess; # request body delayed in limit_req -my $sess = new_session(); -my $sid = new_stream($sess, { path => '/proxy_limit_req/', body_more => 1 }); -h2_body($sess, 'TEST'); -my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +my $s = Test::Nginx::HTTP2->new(); +my $sid = $s->new_stream({ path => '/proxy_limit_req/', body_more => 1 }); +$s->h2_body('TEST'); +my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is(read_body_file($frame->{headers}->{'x-body-file'}), 'TEST', @@ -84,11 +84,11 @@ is(read_body_file($frame->{headers}->{'x TODO: { local $TODO = 'not yet' unless $t->has_version('1.9.15'); -$sess = new_session(); -$sid = new_stream($sess, { path => '/proxy_limit_req/', body_more => 1 }); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/proxy_limit_req/', body_more => 1 }); select undef, undef, undef, 1.1; -h2_body($sess, 'TEST'); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TEST'); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is(read_body_file($frame->{headers}->{'x-body-file'}), 'TEST', @@ -99,28 +99,28 @@ is(read_body_file($frame->{headers}->{'x # request body delayed in limit_req - with an empty DATA frame # "zero size buf in output" alerts seen -$sess = new_session(); -$sid = new_stream($sess, { path => '/proxy_limit_req/', body_more => 1 }); -h2_body($sess, ''); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/proxy_limit_req/', body_more => 1 }); +$s->h2_body(''); select undef, undef, undef, 1.1; -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'request body - limit req - empty'); # predict send windows -$sid = new_stream($sess); -my ($maxwin) = sort {$a <=> $b} $sess->{streams}{$sid}, $sess->{conn_window}; +$sid = $s->new_stream(); +my ($maxwin) = sort {$a <=> $b} $s->{streams}{$sid}, $s->{conn_window}; SKIP: { skip 'leaves coredump', 1 unless $t->has_version('1.9.7'); skip 'not enough window', 1 if $maxwin < 5; -$sess = new_session(); -$sid = new_stream($sess, { path => '/proxy_limit_req/', body => 'TEST2' }); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/proxy_limit_req/', body => 'TEST2' }); select undef, undef, undef, 1.1; -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is(read_body_file($frame->{headers}->{'x-body-file'}), 'TEST2', @@ -131,7 +131,7 @@ is(read_body_file($frame->{headers}->{'x # partial request body data frame received (to be discarded) within request # delayed in limit_req, the rest of data frame is received after response -$sess = new_session(); +$s = Test::Nginx::HTTP2->new(); SKIP: { skip 'not enough window', 1 if $maxwin < 4; @@ -140,9 +140,9 @@ TODO: { todo_skip 'use-after-free', 1 unless $ENV{TEST_NGINX_UNSAFE} or $t->has_version('1.9.12'); -$sid = new_stream($sess, { path => '/limit_req', body => 'TEST', split => [61], +$sid = $s->new_stream({ path => '/limit_req', body => 'TEST', split => [61], split_delay => 1.1 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, '200', 'discard body - limit req - limited'); @@ -151,8 +151,8 @@ is($frame->{headers}->{':status'}, '200' } -$sid = new_stream($sess, { path => '/' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$sid = $s->new_stream({ path => '/' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, '200', 'discard body - limit req - next'); @@ -167,12 +167,12 @@ TODO: { todo_skip 'use-after-free', 1 unless $ENV{TEST_NGINX_UNSAFE} or $t->has_version('1.9.12'); -$sess = new_session(); -$sid = new_stream($sess, { path => '/limit_req', body => 'TEST', split => [61], +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/limit_req', body => 'TEST', split => [61], abort => 1 }); select undef, undef, undef, 1.1; -close $sess->{socket}; +close $s->{socket}; pass('discard body - limit req - eof'); diff --git a/h2_priority.t b/h2_priority.t --- a/h2_priority.t +++ b/h2_priority.t @@ -16,7 +16,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame /; +use Test::Nginx::HTTP2; ############################################################################### @@ -57,21 +57,21 @@ EOF # stream muliplexing + PRIORITY frames -my $sess = new_session(); -my $sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +my $s = Test::Nginx::HTTP2->new(); +my $sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -my $sid2 = new_stream($sess, { path => '/t2.html' }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +my $sid2 = $s->new_stream({ path => '/t2.html' }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -h2_priority($sess, 0, $sid); -h2_priority($sess, 255, $sid2); +$s->h2_priority(0, $sid); +$s->h2_priority(255, $sid2); -h2_window($sess, 2**17, $sid); -h2_window($sess, 2**17, $sid2); -h2_window($sess, 2**17); +$s->h2_window(2**17, $sid); +$s->h2_window(2**17, $sid2); +$s->h2_window(2**17); -my $frames = h2_read($sess, all => [ +my $frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 } ]); @@ -81,21 +81,21 @@ is(join(' ', map { $_->{sid} } @data), " # and vice versa -$sess = new_session(); -$sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t2.html' }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +$sid2 = $s->new_stream({ path => '/t2.html' }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -h2_priority($sess, 255, $sid); -h2_priority($sess, 0, $sid2); +$s->h2_priority(255, $sid); +$s->h2_priority(0, $sid2); -h2_window($sess, 2**17, $sid); -h2_window($sess, 2**17, $sid2); -h2_window($sess, 2**17); +$s->h2_window(2**17, $sid); +$s->h2_window(2**17, $sid2); +$s->h2_window(2**17); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 } ]); @@ -105,18 +105,18 @@ is(join(' ', map { $_->{sid} } @data), " # stream muliplexing + HEADERS PRIORITY flag -$sess = new_session(); -$sid = new_stream($sess, { path => '/t1.html', prio => 0 }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/t1.html', prio => 0 }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t2.html', prio => 255 }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +$sid2 = $s->new_stream({ path => '/t2.html', prio => 255 }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -h2_window($sess, 2**17, $sid); -h2_window($sess, 2**17, $sid2); -h2_window($sess, 2**17); +$s->h2_window(2**17, $sid); +$s->h2_window(2**17, $sid2); +$s->h2_window(2**17); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 } ]); @@ -127,18 +127,18 @@ is($sids, "$sid2 $sid", 'weight - HEADER # and vice versa -$sess = new_session(); -$sid = new_stream($sess, { path => '/t1.html', prio => 255 }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/t1.html', prio => 255 }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t2.html', prio => 0 }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +$sid2 = $s->new_stream({ path => '/t2.html', prio => 0 }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -h2_window($sess, 2**17, $sid); -h2_window($sess, 2**17, $sid2); -h2_window($sess, 2**17); +$s->h2_window(2**17, $sid); +$s->h2_window(2**17, $sid2); +$s->h2_window(2**17); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 } ]); @@ -151,22 +151,22 @@ is($sids, "$sid $sid2", 'weight - HEADER # PRIORITY frame -$sess = new_session(); +$s = Test::Nginx::HTTP2->new(); -h2_priority($sess, 16, 3, 0); -h2_priority($sess, 16, 1, 3); +$s->h2_priority(16, 3, 0); +$s->h2_priority(16, 1, 3); -$sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t2.html' }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +$sid2 = $s->new_stream({ path => '/t2.html' }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -h2_window($sess, 2**17, $sid); -h2_window($sess, 2**17, $sid2); -h2_window($sess, 2**17); +$s->h2_window(2**17, $sid); +$s->h2_window(2**17, $sid2); +$s->h2_window(2**17); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 }, ]); @@ -177,22 +177,22 @@ is($sids, "$sid2 $sid", 'dependency - PR # and vice versa -$sess = new_session(); +$s = Test::Nginx::HTTP2->new(); -h2_priority($sess, 16, 1, 0); -h2_priority($sess, 16, 3, 1); +$s->h2_priority(16, 1, 0); +$s->h2_priority(16, 3, 1); -$sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t2.html' }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +$sid2 = $s->new_stream({ path => '/t2.html' }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -h2_window($sess, 2**17, $sid); -h2_window($sess, 2**17, $sid2); -h2_window($sess, 2**17); +$s->h2_window(2**17, $sid); +$s->h2_window(2**17, $sid2); +$s->h2_window(2**17); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 }, ]); @@ -207,12 +207,12 @@ is($sids, "$sid $sid2", 'dependency - PR # A stream cannot depend on itself. An endpoint MUST treat this as a # stream error of type PROTOCOL_ERROR. -$sess = new_session(); -$sid = new_stream($sess); -h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream(); +$s->read(all => [{ sid => $sid, fin => 1 }]); -h2_priority($sess, 0, $sid, $sid); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$s->h2_priority(0, $sid, $sid); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); my ($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; is($frame->{sid}, $sid, 'dependency - PRIORITY self - RST_STREAM'); @@ -220,22 +220,22 @@ is($frame->{code}, 1, 'dependency - PRIO # HEADERS PRIORITY flag, reprioritize prior PRIORITY frame records -$sess = new_session(); +$s = Test::Nginx::HTTP2->new(); -h2_priority($sess, 16, 1, 0); -h2_priority($sess, 16, 3, 0); +$s->h2_priority(16, 1, 0); +$s->h2_priority(16, 3, 0); -$sid = new_stream($sess, { path => '/t1.html', dep => 3 }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$sid = $s->new_stream({ path => '/t1.html', dep => 3 }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t2.html' }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +$sid2 = $s->new_stream({ path => '/t2.html' }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -h2_window($sess, 2**17, $sid); -h2_window($sess, 2**17, $sid2); -h2_window($sess, 2**17); +$s->h2_window(2**17, $sid); +$s->h2_window(2**17, $sid2); +$s->h2_window(2**17); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 }, ]); @@ -246,22 +246,22 @@ is($sids, "$sid2 $sid", 'dependency - HE # and vice versa -$sess = new_session(); +$s = Test::Nginx::HTTP2->new(); -h2_priority($sess, 16, 1, 0); -h2_priority($sess, 16, 3, 0); +$s->h2_priority(16, 1, 0); +$s->h2_priority(16, 3, 0); -$sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t2.html', dep => 1 }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +$sid2 = $s->new_stream({ path => '/t2.html', dep => 1 }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -h2_window($sess, 2**17, $sid); -h2_window($sess, 2**17, $sid2); -h2_window($sess, 2**17); +$s->h2_window(2**17, $sid); +$s->h2_window(2**17, $sid2); +$s->h2_window(2**17); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 }, ]); @@ -272,9 +272,9 @@ is($sids, "$sid $sid2", 'dependency - HE # HEADERS - self dependency -$sess = new_session(); -$sid = new_stream($sess, { dep => 1 }); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ dep => 1 }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); ($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; is($frame->{sid}, $sid, 'dependency - HEADERS self - RST_STREAM'); @@ -282,27 +282,27 @@ is($frame->{code}, 1, 'dependency - HEAD # PRIORITY frame, weighted dependencies -$sess = new_session(); +$s = Test::Nginx::HTTP2->new(); -h2_priority($sess, 16, 5, 0); -h2_priority($sess, 255, 1, 5); -h2_priority($sess, 0, 3, 5); +$s->h2_priority(16, 5, 0); +$s->h2_priority(255, 1, 5); +$s->h2_priority(0, 3, 5); -$sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t2.html' }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +$sid2 = $s->new_stream({ path => '/t2.html' }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -my $sid3 = new_stream($sess, { path => '/t2.html' }); -h2_read($sess, all => [{ sid => $sid3, fin => 0x4 }]); +my $sid3 = $s->new_stream({ path => '/t2.html' }); +$s->read(all => [{ sid => $sid3, fin => 0x4 }]); -h2_window($sess, 2**16, 1); -h2_window($sess, 2**16, 3); -h2_window($sess, 2**16, 5); -h2_window($sess, 2**16); +$s->h2_window(2**16, 1); +$s->h2_window(2**16, 3); +$s->h2_window(2**16, 5); +$s->h2_window(2**16); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 }, { sid => $sid3, fin => 1 }, @@ -314,27 +314,27 @@ is($sids, "$sid3 $sid $sid2", 'weighted # and vice versa -$sess = new_session(); +$s = Test::Nginx::HTTP2->new(); -h2_priority($sess, 16, 5, 0); -h2_priority($sess, 0, 1, 5); -h2_priority($sess, 255, 3, 5); +$s->h2_priority(16, 5, 0); +$s->h2_priority(0, 1, 5); +$s->h2_priority(255, 3, 5); -$sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t2.html' }); -h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); +$sid2 = $s->new_stream({ path => '/t2.html' }); +$s->read(all => [{ sid => $sid2, fin => 0x4 }]); -$sid3 = new_stream($sess, { path => '/t2.html' }); -h2_read($sess, all => [{ sid => $sid3, fin => 0x4 }]); +$sid3 = $s->new_stream({ path => '/t2.html' }); +$s->read(all => [{ sid => $sid3, fin => 0x4 }]); -h2_window($sess, 2**16, 1); -h2_window($sess, 2**16, 3); -h2_window($sess, 2**16, 5); -h2_window($sess, 2**16); +$s->h2_window(2**16, 1); +$s->h2_window(2**16, 3); +$s->h2_window(2**16, 5); +$s->h2_window(2**16); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid2, fin => 1 }, { sid => $sid3, fin => 1 }, @@ -348,31 +348,31 @@ is($sids, "$sid3 $sid2 $sid", 'weighted # initial dependency tree: # 1 <- [3] <- 5 -$sess = new_session(); +$s = Test::Nginx::HTTP2->new(); -h2_window($sess, 2**18); +$s->h2_window(2**18); -h2_priority($sess, 16, 1, 0); -h2_priority($sess, 16, 3, 1); -h2_priority($sess, 16, 5, 3); +$s->h2_priority(16, 1, 0); +$s->h2_priority(16, 3, 1); +$s->h2_priority(16, 5, 3); -$sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid2, length => 2**16 - 1 }]); +$sid2 = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid2, length => 2**16 - 1 }]); -$sid3 = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid3, length => 2**16 - 1 }]); +$sid3 = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid3, length => 2**16 - 1 }]); -h2_window($sess, 2**16, $sid2); +$s->h2_window(2**16, $sid2); -$frames = h2_read($sess, all => [{ sid => $sid2, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid2, fin => 1 }]); $sids = join ' ', map { $_->{sid} } grep { $_->{type} eq "DATA" } @$frames; is($sids, $sid2, 'removed dependency'); for (1 .. 40) { - h2_read($sess, all => [{ sid => new_stream($sess), fin => 1 }]); + $s->read(all => [{ sid => $s->new_stream(), fin => 1 }]); } # make circular dependency @@ -380,13 +380,13 @@ for (1 .. 40) { # 5 <- 1 # 1 <- 5 -h2_priority($sess, 16, 1, 5); -h2_priority($sess, 16, 5, 1); +$s->h2_priority(16, 1, 5); +$s->h2_priority(16, 5, 1); -h2_window($sess, 2**16, $sid); -h2_window($sess, 2**16, $sid3); +$s->h2_window(2**16, $sid); +$s->h2_window(2**16, $sid3); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid, fin => 1 }, { sid => $sid3, fin => 1 }, ]); @@ -400,26 +400,26 @@ is($frame->{length}, 81, 'removed depend # PRIORITY - reprioritization with circular dependency - exclusive [5] # 1 <- [5] <- 3 -$sess = new_session(); +$s = Test::Nginx::HTTP2->new(); -h2_window($sess, 2**18); +$s->h2_window(2**18); -h2_priority($sess, 16, 1, 0); -h2_priority($sess, 16, 3, 1); -h2_priority($sess, 16, 5, 1, excl => 1); +$s->h2_priority(16, 1, 0); +$s->h2_priority(16, 3, 1); +$s->h2_priority(16, 5, 1, excl => 1); -$sid = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); +$sid = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]); -$sid2 = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid2, length => 2**16 - 1 }]); +$sid2 = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid2, length => 2**16 - 1 }]); -$sid3 = new_stream($sess, { path => '/t1.html' }); -h2_read($sess, all => [{ sid => $sid3, length => 2**16 - 1 }]); +$sid3 = $s->new_stream({ path => '/t1.html' }); +$s->read(all => [{ sid => $sid3, length => 2**16 - 1 }]); -h2_window($sess, 2**16, $sid); +$s->h2_window(2**16, $sid); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); $sids = join ' ', map { $_->{sid} } grep { $_->{type} eq "DATA" } @$frames; is($sids, $sid, 'exclusive dependency - parent removed'); @@ -427,12 +427,12 @@ is($sids, $sid, 'exclusive dependency - # 5 <- 3 -- current dependency tree before reprioritization # 3 <- 5 -h2_priority($sess, 16, 5, 3); +$s->h2_priority(16, 5, 3); -h2_window($sess, 2**16, $sid2); -h2_window($sess, 2**16, $sid3); +$s->h2_window(2**16, $sid2); +$s->h2_window(2**16, $sid3); -$frames = h2_read($sess, all => [ +$frames = $s->read(all => [ { sid => $sid2, fin => 1 }, { sid => $sid3, fin => 1 }, ]); diff --git a/h2_proxy_protocol.t b/h2_proxy_protocol.t --- a/h2_proxy_protocol.t +++ b/h2_proxy_protocol.t @@ -59,9 +59,9 @@ EOF ############################################################################### my $proxy = 'PROXY TCP4 192.0.2.1 192.0.2.2 1234 5678' . CRLF; -my $sess = new_session(8081, proxy => $proxy); -my $sid = new_stream($sess, { path => '/pp' }); -my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +my $s = Test::Nginx::HTTP2->new(8081, proxy => $proxy); +my $sid = $s->new_stream({ path => '/pp' }); +my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; ok($frame, 'PROXY HEADERS frame'); @@ -70,8 +70,8 @@ is($frame->{headers}->{'x-pp'}, '192.0.2 # invalid PROXY protocol string $proxy = 'BOGUS TCP4 192.0.2.1 192.0.2.2 1234 5678' . CRLF; -$sess = new_session(8081, preface => $proxy, pure => 1); -$frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); +$s = Test::Nginx::HTTP2->new(8081, preface => $proxy, pure => 1); +$frames = $s->read(all => [{ type => 'GOAWAY' }]); ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; ok($frame, 'invalid PROXY - GOAWAY frame'); diff --git a/h2_proxy_request_buffering.t b/h2_proxy_request_buffering.t --- a/h2_proxy_request_buffering.t +++ b/h2_proxy_request_buffering.t @@ -18,7 +18,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame :io /; +use Test::Nginx::HTTP2; ############################################################################### @@ -176,9 +176,9 @@ sub get_body { ) or die "Can't create listening socket: $!\n"; - my $sess = new_session(8080); + my $s = Test::Nginx::HTTP2->new(); my $sid = exists $extra{'content-length'} - ? new_stream($sess, { headers => [ + ? $s->new_stream({ headers => [ { name => ':method', value => 'GET' }, { name => ':scheme', value => 'http' }, { name => ':path', value => $url, }, @@ -186,39 +186,37 @@ sub get_body { { name => 'content-length', value => $extra{'content-length'} }], body_more => 1 }) - : new_stream($sess, { path => $url, body_more => 1 }); + : $s->new_stream({ path => $url, body_more => 1 }); $client = $server->accept() or return; log2c("(new connection $client)"); - $f->{headers} = raw_read($client, '', 1, \&log2i); + $f->{headers} = backend_read($client); my $chunked = $f->{headers} =~ /chunked/; - my $body_read = sub { - my ($s, $buf, $len, $wait) = @_; + $f->{upload} = sub { + my ($body, %extra) = @_; + my $len = length($body); + my $wait = $extra{wait}; + + $s->h2_body($body, { %extra }); + + $body = ''; for (1 .. 10) { - $buf = raw_read($s, $buf, length($buf) + 1, \&log2i, - $wait) or return ''; + my $buf = backend_read($client, $wait) or return ''; + $body .= $buf; my $got = 0; $got += $chunked ? hex $_ : $_ for $chunked - ? $buf =~ /(\w+)\x0d\x0a?\w+\x0d\x0a?/g - : length($buf); + ? $body =~ /(\w+)\x0d\x0a?\w+\x0d\x0a?/g + : length($body); last if $got >= $len; } - return $buf; - }; - - $f->{upload} = sub { - my ($body, %extra) = @_; - - h2_body($sess, $body, { %extra }); - - return $body_read->($client, '', length($body), $extra{wait}); + return $body; }; $f->{http_end} = sub { $client->write(<close; - my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); + my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; return $frame->{headers}->{':status'}; }; return $f; } +sub backend_read { + my ($s, $timo) = @_; + my $buf = ''; + + if (IO::Select->new($s)->can_read($timo || 3)) { + $s->sysread($buf, 16384) or return; + log2i($buf); + } + return $buf; +} + sub log2i { Test::Nginx::log_core('|| <<', @_); } sub log2o { Test::Nginx::log_core('|| >>', @_); } sub log2c { Test::Nginx::log_core('||', @_); } diff --git a/h2_proxy_request_buffering_ssl.t b/h2_proxy_request_buffering_ssl.t --- a/h2_proxy_request_buffering_ssl.t +++ b/h2_proxy_request_buffering_ssl.t @@ -18,7 +18,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame :io /; +use Test::Nginx::HTTP2; ############################################################################### @@ -201,9 +201,9 @@ sub get_body { ) or die "Can't create listening socket: $!\n"; - my $sess = new_session(8080); + my $s = Test::Nginx::HTTP2->new(); my $sid = exists $extra{'content-length'} - ? new_stream($sess, { headers => [ + ? $s->new_stream({ headers => [ { name => ':method', value => 'GET' }, { name => ':scheme', value => 'http' }, { name => ':path', value => $url, }, @@ -211,39 +211,37 @@ sub get_body { { name => 'content-length', value => $extra{'content-length'} }], body_more => 1 }) - : new_stream($sess, { path => $url, body_more => 1 }); + : $s->new_stream({ path => $url, body_more => 1 }); $client = $server->accept() or return; log2c("(new connection $client)"); - $f->{headers} = raw_read($client, '', 1, \&log2i); + $f->{headers} = backend_read($client); my $chunked = $f->{headers} =~ /chunked/; - my $body_read = sub { - my ($s, $buf, $len, $wait) = @_; + $f->{upload} = sub { + my ($body, %extra) = @_; + my $len = length($body); + my $wait = $extra{wait}; + + $s->h2_body($body, { %extra }); + + $body = ''; for (1 .. 10) { - $buf = raw_read($s, $buf, length($buf) + 1, \&log2i, - $wait) or return ''; + my $buf = backend_read($client, $wait) or return ''; + $body .= $buf; my $got = 0; $got += $chunked ? hex $_ : $_ for $chunked - ? $buf =~ /(\w+)\x0d\x0a?\w+\x0d\x0a?/g - : length($buf); + ? $body =~ /(\w+)\x0d\x0a?\w+\x0d\x0a?/g + : length($body); last if $got >= $len; } - return $buf; - }; - - $f->{upload} = sub { - my ($body, %extra) = @_; - - h2_body($sess, $body, { %extra }); - - return $body_read->($client, '', length($body), $extra{wait}); + return $body; }; $f->{http_end} = sub { $client->write(<close; - my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); + my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; return $frame->{headers}->{':status'}; }; return $f; } +sub backend_read { + my ($s, $timo) = @_; + my $buf = ''; + + if (IO::Select->new($s)->can_read($timo || 3)) { + $s->sysread($buf, 16384) or return; + log2i($buf); + } + return $buf; +} + sub log2i { Test::Nginx::log_core('|| <<', @_); } sub log2o { Test::Nginx::log_core('|| >>', @_); } sub log2c { Test::Nginx::log_core('||', @_); } diff --git a/h2_proxy_ssl.t b/h2_proxy_ssl.t --- a/h2_proxy_ssl.t +++ b/h2_proxy_ssl.t @@ -16,7 +16,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame /; +use Test::Nginx::HTTP2; ############################################################################### @@ -86,10 +86,10 @@ foreach my $name ('localhost') { TODO: { local $TODO = 'not yet' unless $t->has_version('1.9.14'); -my $sess = new_session(); -my $sid = new_stream($sess, { path => '/proxy_ssl/', body_more => 1 }); -h2_body($sess, ''); -my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +my $s = Test::Nginx::HTTP2->new(); +my $sid = $s->new_stream({ path => '/proxy_ssl/', body_more => 1 }); +$s->h2_body(''); +my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'empty request body'); diff --git a/h2_request_body.t b/h2_request_body.t --- a/h2_request_body.t +++ b/h2_request_body.t @@ -16,7 +16,7 @@ BEGIN { use FindBin; chdir($FindBin::Bin use lib 'lib'; use Test::Nginx; -use Test::Nginx::HTTP2 qw/ :DEFAULT :frame /; +use Test::Nginx::HTTP2; ############################################################################### @@ -72,37 +72,37 @@ EOF # request body (uses proxied response) -my $sess = new_session(); -my $sid = new_stream($sess, { path => '/proxy2/t.html', body_more => 1 }); -h2_body($sess, 'TEST'); -my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +my $s = Test::Nginx::HTTP2->new(); +my $sid = $s->new_stream({ path => '/proxy2/t.html', body_more => 1 }); +$s->h2_body('TEST'); +my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is(read_body_file($frame->{headers}->{'x-body-file'}), 'TEST', 'request body'); # request body with padding (uses proxied response) -$sess = new_session(); -$sid = new_stream($sess, { path => '/proxy2/t.html', body_more => 1 }); -h2_body($sess, 'TEST', { body_padding => 42 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/proxy2/t.html', body_more => 1 }); +$s->h2_body('TEST', { body_padding => 42 }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is(read_body_file($frame->{headers}->{'x-body-file'}), 'TEST', 'request body with padding'); -$sid = new_stream($sess); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$sid = $s->new_stream(); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, '200', 'request body with padding - next'); # request body sent in multiple DATA frames in a single packet -$sess = new_session(); -$sid = new_stream($sess, { path => '/proxy2/t.html', body_more => 1 }); -h2_body($sess, 'TEST', { body_split => [2] }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/proxy2/t.html', body_more => 1 }); +$s->h2_body('TEST', { body_split => [2] }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is(read_body_file($frame->{headers}->{'x-body-file'}), 'TEST', @@ -110,12 +110,12 @@ is(read_body_file($frame->{headers}->{'x # request body sent in multiple DATA frames, each in its own packet -$sess = new_session(); -$sid = new_stream($sess, { path => '/proxy2/t.html', body_more => 1 }); -h2_body($sess, 'TEST', { body_more => 1 }); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/proxy2/t.html', body_more => 1 }); +$s->h2_body('TEST', { body_more => 1 }); select undef, undef, undef, 0.1; -h2_body($sess, 'MOREDATA'); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('MOREDATA'); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is(read_body_file($frame->{headers}->{'x-body-file'}), 'TESTMOREDATA', @@ -124,10 +124,10 @@ is(read_body_file($frame->{headers}->{'x # request body with an empty DATA frame # "zero size buf in output" alerts seen -$sess = new_session(); -$sid = new_stream($sess, { path => '/proxy2/', body_more => 1 }); -h2_body($sess, ''); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/proxy2/', body_more => 1 }); +$s->h2_body(''); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'request body - empty'); @@ -153,9 +153,9 @@ is(read_body_file($frame->{headers}{'x-b TODO: { local $TODO = 'not yet'; -$sess = new_session(); -$sid = new_stream($sess, { body_more => 1 }); -$frames = h2_read($sess, all => [{ type => 'RST_STREAM' }], wait => 0.5); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1 }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }], wait => 0.5); ($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; is($frame->{code}, 0, 'request body discarded - zero RST_STREAM'); @@ -164,40 +164,38 @@ is($frame->{code}, 0, 'request body disc # malformed request body length not equal to content-length -$sess = new_session(); -$sid = new_stream($sess, - { body_more => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/client_max_body_size', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'content-length', value => '5', mode => 1 }]}); -h2_body($sess, 'TEST'); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TEST'); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 400, 'request body less than content-length'); -$sid = new_stream($sess, - { body_more => 1, headers => [ +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/client_max_body_size', mode => 1 }, { name => ':authority', value => 'localhost', mode => 1 }, { name => 'content-length', value => '3', mode => 1 }]}); -h2_body($sess, 'TEST'); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TEST'); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 400, 'request body more than content-length'); # client_max_body_size -$sess = new_session(); -$sid = new_stream($sess, { path => '/client_max_body_size/t.html', +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/client_max_body_size/t.html', body_more => 1 }); -h2_body($sess, 'TESTTEST12'); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST12'); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'client_max_body_size - status'); @@ -206,22 +204,22 @@ is(read_body_file($frame->{headers}->{'x # client_max_body_size - limited -$sess = new_session(); -$sid = new_stream($sess, { path => '/client_max_body_size/t.html', +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/client_max_body_size/t.html', body_more => 1 }); -h2_body($sess, 'TESTTEST123'); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST123'); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 413, 'client_max_body_size - limited'); # client_max_body_size - many DATA frames -$sess = new_session(); -$sid = new_stream($sess, { path => '/client_max_body_size/t.html', +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/client_max_body_size/t.html', body_more => 1 }); -h2_body($sess, 'TESTTEST12', { body_split => [2] }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST12', { body_split => [2] }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'client_max_body_size many - status'); @@ -230,22 +228,22 @@ is(read_body_file($frame->{headers}->{'x # client_max_body_size - many DATA frames - limited -$sess = new_session(); -$sid = new_stream($sess, { path => '/client_max_body_size/t.html', +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/client_max_body_size/t.html', body_more => 1 }); -h2_body($sess, 'TESTTEST123', { body_split => [2] }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST123', { body_split => [2] }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 413, 'client_max_body_size many - limited'); # client_max_body_size - padded DATA -$sess = new_session(); -$sid = new_stream($sess, { path => '/client_max_body_size/t.html', +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/client_max_body_size/t.html', body_more => 1 }); -h2_body($sess, 'TESTTEST12', { body_padding => 42 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST12', { body_padding => 42 }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, 'client_max_body_size pad - status'); @@ -254,22 +252,22 @@ is(read_body_file($frame->{headers}->{'x # client_max_body_size - padded DATA - limited -$sess = new_session(); -$sid = new_stream($sess, { path => '/client_max_body_size/t.html', +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/client_max_body_size/t.html', body_more => 1 }); -h2_body($sess, 'TESTTEST123', { body_padding => 42 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST123', { body_padding => 42 }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 413, 'client_max_body_size pad - limited'); # client_max_body_size - many padded DATA frames -$sess = new_session(); -$sid = new_stream($sess, { path => '/client_max_body_size/t.html', +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/client_max_body_size/t.html', body_more => 1 }); -h2_body($sess, 'TESTTEST12', { body_padding => 42, body_split => [2] }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST12', { body_padding => 42, body_split => [2] }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -279,11 +277,11 @@ is(read_body_file($frame->{headers}->{'x # client_max_body_size - many padded DATA frames - limited -$sess = new_session(); -$sid = new_stream($sess, { path => '/client_max_body_size/t.html', +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/client_max_body_size/t.html', body_more => 1 }); -h2_body($sess, 'TESTTEST123', { body_padding => 42, body_split => [2] }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST123', { body_padding => 42, body_split => [2] }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 413, @@ -291,14 +289,14 @@ is($frame->{headers}->{':status'}, 413, # request body without content-length -$sess = new_session(); -$sid = new_stream($sess, { body_more => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 2 }, { name => ':scheme', value => 'http', mode => 2 }, { name => ':path', value => '/client_max_body_size', mode => 2 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -h2_body($sess, 'TESTTEST12'); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST12'); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -308,14 +306,14 @@ is(read_body_file($frame->{headers}->{'x # request body without content-length - limited -$sess = new_session(); -$sid = new_stream($sess, { body_more => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 2 }, { name => ':scheme', value => 'http', mode => 2 }, { name => ':path', value => '/client_max_body_size', mode => 2 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -h2_body($sess, 'TESTTEST123'); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST123'); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 413, @@ -323,14 +321,14 @@ is($frame->{headers}->{':status'}, 413, # request body without content-length - many DATA frames -$sess = new_session(); -$sid = new_stream($sess, { body_more => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 2 }, { name => ':scheme', value => 'http', mode => 2 }, { name => ':path', value => '/client_max_body_size', mode => 2 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -h2_body($sess, 'TESTTEST12', { body_split => [2] }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST12', { body_split => [2] }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -340,14 +338,14 @@ is(read_body_file($frame->{headers}->{'x # request body without content-length - many DATA frames - limited -$sess = new_session(); -$sid = new_stream($sess, { body_more => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 2 }, { name => ':scheme', value => 'http', mode => 2 }, { name => ':path', value => '/client_max_body_size', mode => 2 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -h2_body($sess, 'TESTTEST123', { body_split => [2] }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST123', { body_split => [2] }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 413, @@ -355,14 +353,14 @@ is($frame->{headers}->{':status'}, 413, # request body without content-length - padding -$sess = new_session(); -$sid = new_stream($sess, { body_more => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 2 }, { name => ':scheme', value => 'http', mode => 2 }, { name => ':path', value => '/client_max_body_size', mode => 2 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -h2_body($sess, 'TESTTEST12', { body_padding => 42 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST12', { body_padding => 42 }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -372,14 +370,14 @@ is(read_body_file($frame->{headers}->{'x # request body without content-length - padding - limited -$sess = new_session(); -$sid = new_stream($sess, { body_more => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 2 }, { name => ':scheme', value => 'http', mode => 2 }, { name => ':path', value => '/client_max_body_size', mode => 2 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -h2_body($sess, 'TESTTEST123', { body_padding => 42 }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST123', { body_padding => 42 }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 413, @@ -387,14 +385,14 @@ is($frame->{headers}->{':status'}, 413, # request body without content-length - padding with many DATA frames -$sess = new_session(); -$sid = new_stream($sess, { body_more => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 2 }, { name => ':scheme', value => 'http', mode => 2 }, { name => ':path', value => '/client_max_body_size', mode => 2 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -h2_body($sess, 'TESTTEST', { body_padding => 42, body_split => [2] }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST', { body_padding => 42, body_split => [2] }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 200, @@ -404,14 +402,14 @@ is(read_body_file($frame->{headers}->{'x # request body without content-length - padding with many DATA frames - limited -$sess = new_session(); -$sid = new_stream($sess, { body_more => 1, headers => [ +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body_more => 1, headers => [ { name => ':method', value => 'GET', mode => 2 }, { name => ':scheme', value => 'http', mode => 2 }, { name => ':path', value => '/client_max_body_size', mode => 2 }, { name => ':authority', value => 'localhost', mode => 2 }]}); -h2_body($sess, 'TESTTEST123', { body_padding => 42, body_split => [2] }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s->h2_body('TESTTEST123', { body_padding => 42, body_split => [2] }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; is($frame->{headers}->{':status'}, 413, diff --git a/h2_server_tokens.t b/h2_server_tokens.t --- a/h2_server_tokens.t +++ b/h2_server_tokens.t @@ -101,9 +101,9 @@ like(body('/on/404'), qr/nginx\/\d+\.\d+ sub header_server { my ($path) = shift; - my $sess = new_session(); - my $sid = new_stream($sess, { path => $path }); - my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); + my $s = Test::Nginx::HTTP2->new(); + my $sid = $s->new_stream({ path => $path }); + my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; return $frame->{headers}->{'server'}; @@ -112,9 +112,9 @@ sub header_server { sub body { my ($path) = shift; - my $sess = new_session(); - my $sid = new_stream($sess, { path => $path }); - my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); + my $s = Test::Nginx::HTTP2->new(); + my $sid = $s->new_stream({ path => $path }); + my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "DATA" } @$frames; return $frame->{'data'}; diff --git a/h2_ssl.t b/h2_ssl.t --- a/h2_ssl.t +++ b/h2_ssl.t @@ -91,7 +91,7 @@ open STDERR, ">&", \*OLDERR; ############################################################################### -my ($sess, $sid, $frames, $frame); +my ($s, $sid, $frames, $frame); # SSL/TLS connection, NPN @@ -99,9 +99,9 @@ SKIP: { eval { IO::Socket::SSL->can_npn() or die; }; skip 'OpenSSL NPN support required', 1 if $@; -$sess = new_session(8081, SSL => 1, npn => 'h2'); -$sid = new_stream($sess, { path => '/h2' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(8081, SSL => 1, npn => 'h2'); +$sid = $s->new_stream({ path => '/h2' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'h2', 'http variable - npn'); @@ -114,9 +114,9 @@ SKIP: { eval { IO::Socket::SSL->can_alpn() or die; }; skip 'OpenSSL ALPN support required', 1 if $@; -$sess = new_session(8081, SSL => 1, alpn => 'h2'); -$sid = new_stream($sess, { path => '/h2' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(8081, SSL => 1, alpn => 'h2'); +$sid = $s->new_stream({ path => '/h2' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'h2', 'http variable - alpn'); @@ -129,9 +129,9 @@ SKIP: { eval { IO::Socket::SSL->can_npn() or die; }; skip 'OpenSSL NPN support required', 1 if $@; -$sess = new_session(8081, SSL => 1, npn => 'h2'); -$sid = new_stream($sess, { path => '/sp' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(8081, SSL => 1, npn => 'h2'); +$sid = $s->new_stream({ path => '/sp' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'HTTP/2.0', 'server_protocol variable - npn'); @@ -144,9 +144,9 @@ SKIP: { eval { IO::Socket::SSL->can_alpn() or die; }; skip 'OpenSSL ALPN support required', 1 if $@; -$sess = new_session(8081, SSL => 1, alpn => 'h2'); -$sid = new_stream($sess, { path => '/sp' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(8081, SSL => 1, alpn => 'h2'); +$sid = $s->new_stream({ path => '/sp' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'HTTP/2.0', 'server_protocol variable - alpn'); @@ -159,9 +159,9 @@ SKIP: { eval { IO::Socket::SSL->can_npn() or die; }; skip 'OpenSSL NPN support required', 1 if $@; -$sess = new_session(8081, SSL => 1, npn => 'h2'); -$sid = new_stream($sess, { path => '/scheme' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(8081, SSL => 1, npn => 'h2'); +$sid = $s->new_stream({ path => '/scheme' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'https', 'scheme variable - npn'); @@ -174,9 +174,9 @@ SKIP: { eval { IO::Socket::SSL->can_alpn() or die; }; skip 'OpenSSL ALPN support required', 1 if $@; -$sess = new_session(8081, SSL => 1, alpn => 'h2'); -$sid = new_stream($sess, { path => '/scheme' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(8081, SSL => 1, alpn => 'h2'); +$sid = $s->new_stream({ path => '/scheme' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'https', 'scheme variable - alpn'); @@ -189,9 +189,9 @@ SKIP: { eval { IO::Socket::SSL->can_npn() or die; }; skip 'OpenSSL NPN support required', 1 if $@; -$sess = new_session(8081, SSL => 1, npn => 'h2'); -$sid = new_stream($sess, { path => '/https' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(8081, SSL => 1, npn => 'h2'); +$sid = $s->new_stream({ path => '/https' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'on', 'https variable - npn'); @@ -204,9 +204,9 @@ SKIP: { eval { IO::Socket::SSL->can_alpn() or die; }; skip 'OpenSSL ALPN support required', 1 if $@; -$sess = new_session(8081, SSL => 1, alpn => 'h2'); -$sid = new_stream($sess, { path => '/https' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(8081, SSL => 1, alpn => 'h2'); +$sid = $s->new_stream({ path => '/https' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'on', 'https variable - alpn'); diff --git a/h2_ssl_verify_client.t b/h2_ssl_verify_client.t --- a/h2_ssl_verify_client.t +++ b/h2_ssl_verify_client.t @@ -139,13 +139,13 @@ sub get { return undef; } - my $sess = new_session(8443, socket => $s); - my $sid = new_stream($sess, { headers => [ + my $sess = Test::Nginx::HTTP2->new(8443, socket => $s); + my $sid = $sess->new_stream({ headers => [ { name => ':method', value => 'GET', mode => 0 }, { name => ':scheme', value => 'http', mode => 0 }, { name => ':path', value => '/t', mode => 1 }, { name => ':authority', value => $host, mode => 1 }]}); - my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); + my $frames = $sess->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; return $frame->{'headers'}; diff --git a/h2_variables.t b/h2_variables.t --- a/h2_variables.t +++ b/h2_variables.t @@ -63,36 +63,36 @@ EOF # $http2 -my $sess = new_session(); -my $sid = new_stream($sess, { path => '/h2' }); -my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +my $s = Test::Nginx::HTTP2->new(); +my $sid = $s->new_stream({ path => '/h2' }); +my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); my ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'h2c', 'http variable - h2c'); # $server_protocol -$sess = new_session(); -$sid = new_stream($sess, { path => '/sp' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/sp' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'HTTP/2.0', 'server_protocol variable'); # $scheme -$sess = new_session(); -$sid = new_stream($sess, { path => '/scheme' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/scheme' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, 'http', 'scheme variable'); # $https -$sess = new_session(); -$sid = new_stream($sess, { path => '/https' }); -$frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/https' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); ($frame) = grep { $_->{type} eq "DATA" } @$frames; is($frame->{data}, '', 'https variable'); diff --git a/lib/Test/Nginx/HTTP2.pm b/lib/Test/Nginx/HTTP2.pm --- a/lib/Test/Nginx/HTTP2.pm +++ b/lib/Test/Nginx/HTTP2.pm @@ -10,15 +10,6 @@ package Test::Nginx::HTTP2; use warnings; use strict; -use base qw/ Exporter /; -our @EXPORT = qw/ new_session new_stream h2_read /; -our %EXPORT_TAGS = ( - io => [ qw/ raw_write raw_read / ], - frame => [ qw/ h2_ping h2_rst h2_goaway h2_priority h2_window - h2_settings h2_unknown h2_continue h2_body/ ] -); -our @EXPORT_OK = ( @{ $EXPORT_TAGS{'io'} }, @{ $EXPORT_TAGS{'frame'} } ); - use Test::More qw//; use IO::Select; use IO::Socket; @@ -113,7 +104,7 @@ sub h2_body { my $sid = $sess->{last_stream}; if ($len > $sess->{conn_window} || $len > $sess->{streams}{$sid}) { - h2_read($sess, all => [{ type => 'WINDOW_UPDATE' }]); + $sess->read(all => [{ type => 'WINDOW_UPDATE' }]); } if ($len > $sess->{conn_window} || $len > $sess->{streams}{$sid}) { @@ -260,7 +251,7 @@ done: return $ctx->{last_stream}; } -sub h2_read { +sub read { my ($sess, %extra) = @_; my (@got); my $s = $sess->{socket}; @@ -438,7 +429,8 @@ sub raw_write { } } -sub new_session { +sub new { + my $class = shift; my ($port, %extra) = @_; my $s = $extra{socket} || new_socket($port, %extra); @@ -458,12 +450,13 @@ sub new_session { dynamic_decode => [ static_table() ], static_table_size => scalar @{[static_table()]}, iws => 65535, conn_window => 65535, streams => {}}; + bless $ctx, $class; return $ctx if $extra{pure}; # update windows, if any - my $frames = h2_read($ctx, all => [ + my $frames = $ctx->read(all => [ { type => 'WINDOW_UPDATE' }, { type => 'SETTINGS'} ]);