File Coverage

blib/lib/Protocol/HTTP2/Frame/Push_promise.pm
Criterion Covered Total %
statement 12 38 31.5
branch 0 10 0.0
condition 0 5 0.0
subroutine 4 6 66.6
pod 0 2 0.0
total 16 61 26.2


line stmt bran cond sub pod time code
1             package Protocol::HTTP2::Frame::Push_promise;
2 11     11   55 use strict;
  11         19  
  11         305  
3 11     11   53 use warnings;
  11         17  
  11         298  
4 11     11   57 use Protocol::HTTP2::Constants qw(:flags :errors :settings);
  11         21  
  11         2701  
5 11     11   57 use Protocol::HTTP2::Trace qw(tracer);
  11         19  
  11         4268  
6              
7             sub decode {
8 0     0 0   my ( $con, $buf_ref, $buf_offset, $length ) = @_;
9 0           my ( $pad, $offset ) = ( 0, 0 );
10 0           my $frame_ref = $con->decode_context->{frame};
11              
12             # Protocol errors
13 0 0 0       if (
14             # PP frames MUST be associated with a stream
15             $frame_ref->{stream} == 0
16              
17             # PP frames MUST be allowed
18             || !$con->dec_setting(SETTINGS_ENABLE_PUSH)
19             )
20             {
21 0           $con->error(PROTOCOL_ERROR);
22 0           return undef;
23             }
24              
25 0 0         if ( $frame_ref->{flags} & PADDED ) {
26 0           $pad = unpack( 'C', substr( $$buf_ref, $buf_offset ) );
27 0           $offset += 1;
28             }
29              
30 0           my $promised_sid = unpack 'N', substr $$buf_ref, $buf_offset + $offset, 4;
31 0           $promised_sid &= 0x7FFF_FFFF;
32 0           $offset += 4;
33              
34 0           my $hblock_size = $length - $offset - $pad;
35 0 0         if ( $hblock_size < 0 ) {
36 0           tracer->error("Not enough space for header block\n");
37 0           $con->error(FRAME_SIZE_ERROR);
38 0           return undef;
39             }
40              
41 0 0         $con->new_peer_stream($promised_sid) or return undef;
42 0           $con->stream_promised_sid( $frame_ref->{stream}, $promised_sid );
43              
44             $con->stream_header_block( $frame_ref->{stream},
45 0           substr( $$buf_ref, $buf_offset + $offset, $hblock_size ) );
46              
47             # PP header block complete
48             $con->stream_headers_done( $frame_ref->{stream} )
49             or return undef
50 0 0 0       if $frame_ref->{flags} & END_HEADERS;
51              
52 0           return $length;
53              
54             }
55              
56             sub encode {
57 0     0 0   my ( $con, $flags_ref, $stream_id, $data_ref ) = @_;
58 0           my $promised_id = $data_ref->[0];
59 0           my $hblock_ref = $data_ref->[1];
60              
61 0           return pack( 'N', $promised_id ) . $$hblock_ref;
62             }
63              
64             1;