File Coverage

blib/lib/Protocol/HTTP2/Frame/Headers.pm
Criterion Covered Total %
statement 41 49 83.6
branch 10 16 62.5
condition 5 9 55.5
subroutine 6 6 100.0
pod 0 2 0.0
total 62 82 75.6


line stmt bran cond sub pod time code
1             package Protocol::HTTP2::Frame::Headers;
2 10     10   42 use strict;
  10         15  
  10         323  
3 10     10   41 use warnings;
  10         12  
  10         259  
4 10     10   40 use Protocol::HTTP2::Constants qw(:flags :errors :states :limits);
  10         12  
  10         2403  
5 10     10   57 use Protocol::HTTP2::Trace qw(tracer);
  10         14  
  10         4179  
6              
7             # 6.2 HEADERS
8             sub decode {
9 24     24 0 3932 my ( $con, $buf_ref, $buf_offset, $length ) = @_;
10 24         4087 my ( $pad, $offset, $weight, $exclusive, $stream_dep ) = ( 0, 0 );
11 24         4342 my $frame_ref = $con->decode_context->{frame};
12              
13             # Protocol errors
14 24 50       4041 if (
15             # HEADERS frames MUST be associated with a stream
16             $frame_ref->{stream} == 0
17             )
18             {
19 0         0 $con->error(PROTOCOL_ERROR);
20 0         0 return undef;
21             }
22              
23 24 50       4008 if ( $frame_ref->{flags} & PADDED ) {
24 0         0 $pad = unpack( 'C', substr( $$buf_ref, $buf_offset, 1 ) );
25 0         0 $offset += 1;
26             }
27              
28 24 100       3958 if ( $frame_ref->{flags} & PRIORITY_FLAG ) {
29 1         4 ( $stream_dep, $weight ) =
30             unpack( 'NC', substr( $$buf_ref, $buf_offset + $offset, 5 ) );
31 1         1 $exclusive = $stream_dep >> 31;
32 1         1 $stream_dep &= 0x7FFF_FFFF;
33 1         2 $weight++;
34              
35 1         3 $con->stream_weight( $frame_ref->{stream}, $weight );
36 1         3 $con->stream_reprio( $frame_ref->{stream}, $exclusive, $stream_dep, );
37              
38 1         1 $offset += 5;
39             }
40              
41             # Not enough space for header block
42 24         4047 my $hblock_size = $length - $offset - $pad;
43 24 50       4199 if ( $hblock_size < 0 ) {
44 0         0 $con->error(FRAME_SIZE_ERROR);
45 0         0 return undef;
46             }
47              
48 24         4244 $con->stream_header_block( $frame_ref->{stream},
49             substr( $$buf_ref, $buf_offset + $offset, $hblock_size ) );
50              
51             # Stream header block complete
52 24 50 50     4472 $con->stream_headers_done( $frame_ref->{stream} )
53             or return undef
54             if $frame_ref->{flags} & END_HEADERS;
55              
56 24         8176 return $length;
57             }
58              
59             sub encode {
60 27     27 0 3999 my ( $con, $flags_ref, $stream, $data_ref ) = @_;
61 27         3952 my $res = '';
62              
63 27 50       3937 if ( exists $data_ref->{padding} ) {
64 0         0 $$flags_ref |= PADDED;
65 0         0 $res .= pack 'C', $data_ref->{padding};
66             }
67              
68 27 100 66     4117 if ( exists $data_ref->{stream_dep} || exists $data_ref->{weight} ) {
69 1         2 $$flags_ref |= PRIORITY_FLAG;
70 1   50     3 my $weight = ( $data_ref->{weight} || DEFAULT_WEIGHT ) - 1;
71 1   50     5 my $stream_dep = $data_ref->{stream_dep} || 0;
72 1 50       3 $stream_dep |= ( 1 << 31 ) if $data_ref->{exclusive};
73 1         3 $res .= pack 'NC', $stream_dep, $weight;
74             }
75              
76 27         3995 return $res . ${ $data_ref->{hblock} };
  27         12224  
77             }
78              
79             1;