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 11     11   54 use strict;
  11         20  
  11         297  
3 11     11   50 use warnings;
  11         18  
  11         301  
4 11     11   51 use Protocol::HTTP2::Constants qw(:flags :errors :settings :limits);
  11         17  
  11         3404  
5 11     11   60 use Protocol::HTTP2::Trace qw(tracer);
  11         16  
  11         5536  
6              
7             sub decode {
8 31     31 0 5464 my ( $con, $buf_ref, $buf_offset, $length ) = @_;
9 31         5540 my ( $pad, $offset ) = ( 0, 0 );
10 31         5515 my $frame_ref = $con->decode_context->{frame};
11              
12             # Protocol errors
13 31 50       5543 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 31 50       5562 if ( $frame_ref->{flags} & PADDED ) {
23 0         0 $pad = unpack( 'C', substr( $$buf_ref, $buf_offset ) );
24 0         0 $offset += 1;
25             }
26              
27 31         5487 my $dblock_size = $length - $offset - $pad;
28 31 50       5489 if ( $dblock_size < 0 ) {
29 0         0 tracer->error("Not enough space for data block\n");
30 0         0 $con->error(FRAME_SIZE_ERROR);
31 0         0 return undef;
32             }
33              
34 31         5554 my $fcw = $con->fcw_recv( -$length );
35 31         5686 my $stream_fcw = $con->stream_fcw_recv( $frame_ref->{stream}, -$length );
36 31 50 33     5665 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 31 100       5558 $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 31 50 33     5514 && !( $frame_ref->{flags} & END_STREAM );
46              
47 31 100       6880 return $length unless $dblock_size;
48              
49 23         4177 my $data = substr $$buf_ref, $buf_offset + $offset, $dblock_size;
50              
51             # Update stream data container
52 23         4196 $con->stream_data( $frame_ref->{stream}, $data );
53              
54             # Check length of data matched content-length in header
55 23 100       4171 if ( $frame_ref->{flags} & END_STREAM ) {
56 4         22 my $slen = $con->stream_length( $frame_ref->{stream} );
57 4 50 66     48 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         8229 return $length;
67             }
68              
69             sub encode {
70 31     31 0 5434 my ( $con, $flags_ref, $stream_id, $data_ref ) = @_;
71              
72 31         10888 return $$data_ref;
73             }
74              
75             1;