File Coverage

blib/lib/Protocol/HTTP2/Frame/Data.pm
Criterion Covered Total %
statement 33 45 73.3
branch 12 18 66.6
condition 4 9 44.4
subroutine 6 6 100.0
pod 0 2 0.0
total 55 80 68.7


line stmt bran cond sub pod time code
1             package Protocol::HTTP2::Frame::Data;
2 12     12   40 use strict;
  12         10  
  12         263  
3 12     12   36 use warnings;
  12         11  
  12         256  
4 12     12   34 use Protocol::HTTP2::Constants qw(:flags :errors :settings :limits);
  12         11  
  12         2546  
5 12     12   49 use Protocol::HTTP2::Trace qw(tracer);
  12         19  
  12         4058  
6              
7             sub decode {
8 52     52 0 3222 my ( $con, $buf_ref, $buf_offset, $length ) = @_;
9 52         3277 my ( $pad, $offset ) = ( 0, 0 );
10 52         3272 my $frame_ref = $con->decode_context->{frame};
11              
12             # Protocol errors
13 52 50       3255 if (
14             # DATA frames MUST be associated with a stream
15             $frame_ref->{stream} == 0
16             )
17             {
18 0         0 $con->error(PROTOCOL_ERROR);
19 0         0 return undef;
20             }
21              
22 52 50       3286 if ( $frame_ref->{flags} & PADDED ) {
23 0         0 $pad = unpack( 'C', substr( $$buf_ref, $buf_offset ) );
24 0         0 $offset += 1;
25             }
26              
27 52         3226 my $dblock_size = $length - $offset - $pad;
28 52 50       3524 if ( $dblock_size < 0 ) {
29 0         0 tracer->error("Not enough space for data block\n");
30 0         0 $con->error(PROTOCOL_ERROR);
31 0         0 return undef;
32             }
33              
34 52         3280 my $fcw = $con->fcw_recv( -$length );
35 52         3362 my $stream_fcw = $con->stream_fcw_recv( $frame_ref->{stream}, -$length );
36 52 50 33     3411 if ( $fcw < 0 || $stream_fcw < 0 ) {
37 0         0 tracer->warning(
38             "received data overflow flow control window: $fcw|$stream_fcw\n");
39 0         0 $con->stream_error( $frame_ref->{stream}, FLOW_CONTROL_ERROR );
40 0         0 return $length;
41             }
42 52 100       3256 $con->fcw_update() if $fcw < $con->dec_setting(SETTINGS_MAX_FRAME_SIZE);
43             $con->stream_fcw_update( $frame_ref->{stream} )
44             if $stream_fcw < $con->dec_setting(SETTINGS_MAX_FRAME_SIZE)
45 52 50 33     3286 && !( $frame_ref->{flags} & END_STREAM );
46              
47 52 100       4148 return $length unless $dblock_size;
48              
49 23         2453 my $data = substr $$buf_ref, $buf_offset + $offset, $dblock_size;
50              
51             # Update stream data container
52 23         2451 $con->stream_data( $frame_ref->{stream}, $data );
53              
54             # Check length of data matched content-length in header
55 23 100       2447 if ( $frame_ref->{flags} & END_STREAM ) {
56 4         15 my $slen = $con->stream_length( $frame_ref->{stream} );
57 4 50 66     28 if ( defined $slen
58             && $slen != length $con->stream_data( $frame_ref->{stream} ) )
59             {
60 0         0 tracer->warning(
61             "content-length header don't match data frames size\n");
62 0         0 $con->stream_error( $frame_ref->{stream}, PROTOCOL_ERROR );
63             }
64             }
65              
66 23         4812 return $length;
67             }
68              
69             sub encode {
70 52     52 0 3217 my ( $con, $flags_ref, $stream_id, $data_ref ) = @_;
71              
72 52         6458 return $$data_ref;
73             }
74              
75             1;