diff options
Diffstat (limited to '')
-rw-r--r-- | web/server/h2o/libh2o/misc/p5-net-fastcgi/t/020_protocol/050_parse_record.t | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/misc/p5-net-fastcgi/t/020_protocol/050_parse_record.t b/web/server/h2o/libh2o/misc/p5-net-fastcgi/t/020_protocol/050_parse_record.t new file mode 100644 index 000000000..34c5fb923 --- /dev/null +++ b/web/server/h2o/libh2o/misc/p5-net-fastcgi/t/020_protocol/050_parse_record.t @@ -0,0 +1,180 @@ +#!perl + +use strict; +use warnings; + +use lib 't/lib', 'lib'; +use myconfig; + +use Test::More tests => 54; +use Test::HexString; +use Test::Exception; + +BEGIN { + use_ok('Net::FastCGI::Constant', qw[:all]); + use_ok('Net::FastCGI::Protocol', qw[ build_header + build_record + build_stream + parse_record ]); +} + +my @records_ok = ( + [ + "\x01\x01\x00\x01\x00\x08\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00", + "\x00\x01\x00\x00\x00\x00\x00\x00", + { type => FCGI_BEGIN_REQUEST, + request_id => 1, + role => FCGI_RESPONDER, + flags => 0 } + ], + [ + "\x01\x02\x00\x01\x00\x00\x00\x00", + "", + { type => FCGI_ABORT_REQUEST, + request_id => 1 } + ], + [ + "\x01\x03\x00\x01\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00", + { type => FCGI_END_REQUEST, + request_id => 1, + protocol_status => 0, + app_status => 0 } + ], + [ + "\x01\x04\x00d\x00\x0B\x05\x00FCGI_PARAMS\x00\x00\x00\x00\x00", + "FCGI_PARAMS", + { type => FCGI_PARAMS, + request_id => 100, + content => 'FCGI_PARAMS' } + ], + [ + "\x01\x05\x00\xC8\x00\x0A\x06\x00FCGI_STDIN\x00\x00\x00\x00\x00\x00", + "FCGI_STDIN", + { type => FCGI_STDIN, + request_id => 200, + content => 'FCGI_STDIN' } + ], + [ + "\x01\x06\x01\x2C\x00\x0B\x05\x00FCGI_STDOUT\x00\x00\x00\x00\x00", + "FCGI_STDOUT", + { type => FCGI_STDOUT, + request_id => 300, + content => 'FCGI_STDOUT' } + ], + [ + "\x01\x07\x01\x90\x00\x0B\x05\x00FCGI_STDERR\x00\x00\x00\x00\x00", + "FCGI_STDERR", + { type => FCGI_STDERR, + request_id => 400, + content => 'FCGI_STDERR' } + ], + [ + "\x01\x08\x01\xF4\x00\x09\x07\x00FCGI_DATA\x00\x00\x00\x00\x00\x00\x00", + "FCGI_DATA", + { type => FCGI_DATA, + request_id => 500, + content => 'FCGI_DATA' } + ], + [ + "\x01\x09\x00\x00\x00\x0D\x03\x00\x03\x03BarBaZ\x03\x00FOO\x00\x00\x00", + "\x03\x03BarBaZ\x03\x00FOO", + { type => FCGI_GET_VALUES, + request_id => FCGI_NULL_REQUEST_ID, + values => { FOO => '', Bar => 'BaZ' } + } + ], + [ + "\x01\x0A\x00\x00\x00\x17\x01\x00\x04\x01BETA2\x05\x01ALPHA1\x05\x01GAMMA3\x00", + "\x04\x01BETA2\x05\x01ALPHA1\x05\x01GAMMA3", + { type => FCGI_GET_VALUES_RESULT, + request_id => FCGI_NULL_REQUEST_ID, + values => { ALPHA => 1, BETA => 2, GAMMA => 3 } + } + ], + [ + "\x01\x0B\x00\x00\x00\x08\x00\x00\x64\x00\x00\x00\x00\x00\x00\x00", + "\x64\x00\x00\x00\x00\x00\x00\x00", + { type => FCGI_UNKNOWN_TYPE, + request_id => FCGI_NULL_REQUEST_ID, + unknown_type => 100 } + ], + [ + "\x01\x6F\x00\xDE\x00\x04\x04\x00oops\x00\x00\x00\x00", + "oops", + { type => 111, + request_id => 222, + content => 'oops' } + ], + [ + "\x01\xFF\xFF\xFF\x00\x00\x00\x00", + "", + { type => 0xFF, + request_id => 0xFFFF } + ], +); + +foreach my $test (@records_ok) { + my $expected = $test->[2]; + my $got = parse_record($test->[0]); + is_deeply($got, $expected, "parse_record() in scalar context"); +} + +foreach my $test (@records_ok) { + my @expected = ($test->[2]->{type}, $test->[2]->{request_id}, $test->[1]); + my @got = parse_record($test->[0]); + is_deeply(\@got, \@expected, "parse_record() in list context"); +} + +my @headers_malformed = ( + # type, request_id, content_length, padding_length + [ FCGI_BEGIN_REQUEST, 0, 0, 0 ], + [ FCGI_BEGIN_REQUEST, 1, 0, 0 ], + [ FCGI_ABORT_REQUEST, 0, 0, 0 ], + [ FCGI_END_REQUEST, 0, 0, 0 ], + [ FCGI_END_REQUEST, 1, 0, 0 ], + [ FCGI_PARAMS, 0, 0, 0 ], + [ FCGI_STDIN, 0, 0, 0 ], + [ FCGI_STDOUT, 0, 0, 0 ], + [ FCGI_STDERR, 0, 0, 0 ], + [ FCGI_DATA, 0, 0, 0 ], + [ FCGI_GET_VALUES, 1, 0, 0 ], + [ FCGI_GET_VALUES_RESULT, 1, 0, 0 ], + [ FCGI_UNKNOWN_TYPE, 0, 0, 0 ], + [ FCGI_UNKNOWN_TYPE, 1, 0, 0 ] +); + +foreach my $test (@headers_malformed) { + my $octets = build_header(@$test); + throws_ok { parse_record($octets) } qr/^FastCGI: Malformed/; +} + +{ + my $octets = build_header(FCGI_ABORT_REQUEST, 1, 8, 0) . "\x00" x 8; + throws_ok { parse_record($octets) } qr/^FastCGI: Malformed/; +} + +my @stream_types = ( + FCGI_PARAMS, + FCGI_STDIN, + FCGI_STDOUT, + FCGI_STDERR, + FCGI_DATA +); + +foreach my $type (@stream_types) { + my $expected = { type => $type, request_id => 1, content => '' }; + my $octets = build_record($type, 1, ''); + my $got = parse_record($octets); + is_deeply($got, $expected, "parse_record(stream record) in scalar context"); +} + +foreach my $type (@stream_types) { + my @expected = ($type, 1, ''); + my $octets = build_record($type, 1, ''); + my @got = parse_record($octets); + is_deeply(\@got, \@expected, "parse_record(stream record) in list context"); +} + +throws_ok { parse_record() } qr/^Usage: /; + |