File Coverage

blib/lib/Protocol/HTTP2/Frame/Data.pm
Criterion Covered Total %
statement 33 45 73.3
branch 11 18 61.1
condition 3 9 33.3
subroutine 6 6 100.0
pod 0 2 0.0
total 53 80 66.2


line stmt bran cond sub pod time code
1             package Protocol::HTTP2::Frame::Data;
2 10     10   41 use strict;
  10         15  
  10         348  
3 10     10   41 use warnings;
  10         14  
  10         246  
4 10     10   69 use Protocol::HTTP2::Constants qw(:flags :errors :settings :limits);
  10         10  
  10         2413  
5 10     10   55 use Protocol::HTTP2::Trace qw(tracer);
  10         15  
  10         4095  
6              
7             sub decode {
8 22     22 0 3990 my ( $con, $buf_ref, $buf_offset, $length ) = @_;
9 22         3934 my ( $pad, $offset ) = ( 0, 0 );
10 22         4081 my $frame_ref = $con->decode_context->{frame};
11              
12             # Protocol errors
13 22 50       4002 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 22 50       4081 if ( $frame_ref->{flags} & PADDED ) {
23 0         0 $pad = unpack( 'C', substr( $$buf_ref, $buf_offset ) );
24 0         0 $offset += 1;
25             }
26              
27 22         4053 my $dblock_size = $length - $offset - $pad;
28 22 50       3991 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 22         4010 my $fcw = $con->fcw_recv( -$length );
35 22         4108 my $stream_fcw = $con->stream_fcw_recv( $frame_ref->{stream}, -$length );
36 22 50 33     4205 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 22 50       4077 $con->fcw_update() if $fcw < $con->dec_setting(SETTINGS_MAX_FRAME_SIZE);
43 22 50 33     4034 $con->stream_fcw_update( $frame_ref->{stream} )
44             if $stream_fcw < $con->dec_setting(SETTINGS_MAX_FRAME_SIZE)
45             && !( $frame_ref->{flags} & END_STREAM );
46              
47 22 100       5262 return $length unless $dblock_size;
48              
49 17         3297 my $data = substr $$buf_ref, $buf_offset + $offset, $dblock_size;
50              
51             # Update stream data container
52 17         3600 $con->stream_data( $frame_ref->{stream}, $data );
53              
54             # Check length of data matched content-length in header
55 17 100       3360 if ( $frame_ref->{flags} & END_STREAM ) {
56 2         8 my $slen = $con->stream_length( $frame_ref->{stream} );
57 2 50 33     22 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 17         6256 return $length;
67             }
68              
69             sub encode {
70 22     22 0 4017 my ( $con, $flags_ref, $stream_id, $data_ref ) = @_;
71              
72 22         7801 return $$data_ref;
73             }
74              
75             1;