# HG changeset patch # User Sergey Kandaurov # Date 1466531168 -10800 # Node ID b9692ec5a08b66b270fa9627e1058b2eece81024 # Parent 2bbab9bd73e5628273526e31e4845907043e2b9a Tests: HTTP/2 request body preread tests. diff --git a/h2_request_body_preread.t b/h2_request_body_preread.t new file mode 100644 --- /dev/null +++ b/h2_request_body_preread.t @@ -0,0 +1,184 @@ +#!/usr/bin/perl + +# (C) Sergey Kandaurov +# (C) Nginx, Inc. + +# Tests for HTTP/2 protocol with preread request body. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; +use Test::Nginx::HTTP2; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http http_v2 proxy limit_req shmem/); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + limit_req_zone $binary_remote_addr zone=req:1m rate=1r/s; + + server { + listen 127.0.0.1:%%PORT_0%% http2; + listen 127.0.0.1:%%PORT_1%%; + server_name localhost; + + http2_body_preread_size 10; + + location /t { } + location / { + add_header X-Body $request_body; + proxy_pass http://127.0.0.1:%%PORT_1%%/t; + + location /req { + limit_req zone=req burst=2; + proxy_pass http://127.0.0.1:%%PORT_1%%/t; + } + } + } + + server { + listen 127.0.0.1:%%PORT_2%% http2; + server_name localhost; + + http2_body_preread_size 0; + + location / { + add_header X-Body $request_body; + proxy_pass http://127.0.0.1:%%PORT_1%%/t; + + location /req { + limit_req zone=req burst=2; + proxy_pass http://127.0.0.1:%%PORT_1%%/t; + } + } + } + + server { + listen 127.0.0.1:%%PORT_3%% http2; + server_name localhost; + + location / { + add_header X-Body $request_body; + proxy_pass http://127.0.0.1:%%PORT_1%%/t; + } + } +} + +EOF + +$t->write_file('t', ''); +$t->try_run('no http2_body_preread_size')->plan(8); + +############################################################################### + +# request body within preread size (that is, stream window) + +my $s = Test::Nginx::HTTP2->new(); +my $sid = $s->new_stream({ body => 'TEST' }); +my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]); + +my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; +is($frame->{headers}->{'x-body'}, 'TEST', 'within preread'); + +# request body beyond preread size +# RST_STREAM expected due stream window violation + +TODO: { +local $TODO = 'not yet'; + +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ body => 'TEST' x 10 }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }], wait => 0.5); + +($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; +is($frame->{code}, 3, 'beyond preread - FLOW_CONTROL_ERROR'); + +} + +# within preread size - limited + +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/req' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); + +$sid = $s->new_stream({ path => '/req', body => 'TEST' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); + +($frame) = grep { $_->{type} eq "HEADERS" } @$frames; +is($frame->{headers}->{'x-body'}, 'TEST', 'within preread limited'); + +# beyond preread size - limited + +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/req', body => 'TEST' x 10 }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); + +($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; +is($frame->{code}, 3, 'beyond preread limited - FLOW_CONTROL_ERROR'); + + +# zero preread size + +TODO: { +local $TODO = 'not yet'; + +$s = Test::Nginx::HTTP2->new(port(2)); +$sid = $s->new_stream({ body => 'TEST' }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }], wait => 0.5); + +($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; +is($frame->{code}, 3, 'zero preread - FLOW_CONTROL_ERROR'); + +} + +# zero preread size - limited + +$s = Test::Nginx::HTTP2->new(port(2)); +$sid = $s->new_stream({ path => '/req', body => 'TEST' }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); + +($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; +is($frame->{code}, 3, 'zero preread limited - FLOW_CONTROL_ERROR'); + + +# REFUSED_STREAM on request body prior SETTINGS acknowledgement + +$s = Test::Nginx::HTTP2->new(port(0), pure => 1); +$sid = $s->new_stream({ body => 'TEST' }); +$frames = $s->read(all => [{ type => 'RST_STREAM' }]); + +($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; +is($frame->{code}, 7, 'no SETTINGS ack - REFUSED_STREAM'); + +# default preread size - no REFUSED_STREAM expected + +$s = Test::Nginx::HTTP2->new(port(3), pure => 1); +$sid = $s->new_stream({ body => 'TEST' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); + +($frame) = grep { $_->{type} eq "HEADERS" } @$frames; +is($frame->{headers}->{'x-body'}, 'TEST', 'no SETTINGS ack - default preread'); + +###############################################################################