# HG changeset patch # User Sergey Kandaurov # Date 1497881459 -10800 # Node ID ae3a46305e383f730c7cd6c3f78ba97a6f7269d5 # Parent 366d789f3cbf5f6ffe9e021400647a63a5c4aa73 Tests: add_trailer tests. diff --git a/h2_trailers.t b/h2_trailers.t new file mode 100644 --- /dev/null +++ b/h2_trailers.t @@ -0,0 +1,134 @@ +#!/usr/bin/perl + +# (C) Sergey Kandaurov +# (C) Nginx, Inc. + +# Tests for HTTP/2 trailers. + +############################################################################### + +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/) + ->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080 http2; + server_name localhost; + + location / { + add_trailer X-Var $host; + } + + http2_max_field_size 256k; + + location /continuation { + # many trailers to send in parts + add_trailer X-LongHeader $arg_h; + add_trailer X-LongHeader $arg_h; + add_trailer X-LongHeader $arg_h; + add_trailer X-LongHeader $arg_h; + add_trailer X-LongHeader $arg_h; + } + } +} + +EOF + +$t->write_file('index.html', 'SEE-THIS'); +$t->write_file('empty', ''); +$t->write_file('continuation', 'SEE-THIS'); +$t->try_run('no add_trailer')->plan(22); + +############################################################################### + +my ($s, $sid, $frames, $frame); + +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); +@$frames = grep { $_->{type} =~ "HEADERS|DATA" } @$frames; + +is(@$frames, 3, 'frames'); + +$frame = shift @$frames; +is($frame->{headers}->{':status'}, 200, 'header'); +is($frame->{headers}->{'x-var'}, undef, 'header not trailer'); +is($frame->{flags}, 4, 'header flags'); + +$frame = shift @$frames; +is($frame->{data}, 'SEE-THIS', 'data'); +is($frame->{flags}, 0, 'data flags'); + +$frame = shift @$frames; +is($frame->{headers}->{'x-var'}, 'localhost', 'trailer'); +is($frame->{flags}, 5, 'trailer flags'); + +# with zero content-length + +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/empty' }); +$frames = $s->read(all => [{ sid => $sid, fin => 1 }]); +@$frames = grep { $_->{type} =~ "HEADERS|DATA" } @$frames; + +is(@$frames, 2, 'no data - frames'); + +$frame = shift @$frames; +is($frame->{headers}->{':status'}, 200, 'no data - header'); +is($frame->{flags}, 4, 'no data - header flags'); + +$frame = shift @$frames; +is($frame->{headers}->{'x-var'}, 'localhost', 'no data - trailer'); +is($frame->{flags}, 5, 'no data - trailer flags'); + +# CONTINUATION in response trailers + +$s = Test::Nginx::HTTP2->new(); +$sid = $s->new_stream({ path => '/continuation?h=' . 'x' x 2**12 }); +$frames = $s->read(all => [{ sid => $sid, fin => 0x4 }]); +push @$frames, @{$s->read(all => [{ sid => $sid, fin => 0x4 }])}; +@$frames = grep { $_->{type} =~ "HEADERS|CONTINUATION|DATA" } @$frames; + +is(@$frames, 4, 'continuation - frames'); + +$frame = shift @$frames; +is($frame->{headers}->{':status'}, 200, 'continuation - header'); +is($frame->{flags}, 4, 'continuation - header flags'); + +$frame = shift @$frames; +is($frame->{data}, 'SEE-THIS', 'continuation - data'); +is($frame->{flags}, 0, 'continuation - data flags'); + +$frame = shift @$frames; +is($frame->{type}, 'HEADERS', 'continuation - trailer'); +is($frame->{flags}, 1, 'continuation - trailer flags'); + +$frame = shift @$frames; +is($frame->{type}, 'CONTINUATION', 'continuation - trailer continuation'); +is($frame->{flags}, 4, 'continuation - trailer continuation flags'); + +############################################################################### diff --git a/trailers.t b/trailers.t new file mode 100644 --- /dev/null +++ b/trailers.t @@ -0,0 +1,134 @@ +#!/usr/bin/perl + +# (C) Sergey Kandaurov +# (C) Nginx, Inc. + +# Tests for trailers in headers filter module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +use Socket qw/ $CRLF /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy/) + ->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + add_trailer X-Var $host; + add_trailer X-Always $host always; + add_trailer X-Empty ''; + add_trailer X-Sent-HTTP $sent_http_accept_ranges; + add_trailer X-Sent-Trailer $sent_trailer_x_var; + add_trailer X-Complex $host:$host; + + location /t1 { + } + + location /nx { + } + + location /header { + add_header X-Var foo; + } + + location /empty { + add_trailer X-Var $host; + } + + location /not_chunked { + chunked_transfer_encoding off; + } + + location /proxy { + proxy_pass http://127.0.0.1:8080/t1; + add_trailer X-Length $upstream_response_length; + } + } +} + +EOF + +$t->write_file('t1', 'SEE-THIS'); +$t->write_file('header', ''); +$t->try_run('no add_trailer')->plan(17); + +############################################################################### + +my $r; + +$r = get('/t1'); +like($r, qr/8${CRLF}SEE-THIS${CRLF}0${CRLF}(.+${CRLF}){5}$CRLF/, 'trailers'); +unlike($r, qr/X-Var.*SEE-THIS/s, 'not in headers'); +like($r, qr/X-Var: localhost/, 'add_trailer'); +like($r, qr/X-Always/, 'add_trailer always'); +like($r, qr/X-Sent-HTTP: bytes/, 'add_trailer sent_http'); +like($r, qr/X-Sent-Trailer: localhost/, 'add_trailer sent_trailer'); +like($r, qr/X-Complex: localhost:localhost/, 'add_trailer complex'); +unlike($r, qr/X-Empty/, 'add_trailer empty'); + +$r = get('/nx'); +unlike($r, qr/X-Var/, 'add_trailer bad'); +like($r, qr/X-Always/, 'add_trailer bad always'); + +like(get('/header'), qr/foo.*^0$CRLF.*X-Var: localhost/ms, 'header name'); + +like(http_get('/t1'), qr/${CRLF}SEE-THIS$/, 'no trailers - http10'); +unlike(get('/not_chunked'), qr/X-Always/, 'no trailers - not chunked'); +unlike(head('/t1'), qr/X-Always/, 'no trailers - head'); + +unlike(get('/empty'), qr/X-Var/, 'no trailers expected'); + +$r = get('/proxy'); +like($r, qr/SEE-THIS.*X-Length: 8/ms, 'upstream response variable'); +unlike($r, qr/X-Var/, 'inheritance'); + +############################################################################### + +sub get { + my ($uri) = @_; + http(<