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 11     11   52 use strict;
  11         20  
  11         288  
3 11     11   56 use warnings;
  11         18  
  11         300  
4 11     11   52 use Protocol::HTTP2::Constants qw(:flags :errors :states :limits);
  11         20  
  11         3454  
5 11     11   58 use Protocol::HTTP2::Trace qw(tracer);
  11         18  
  11         5380  
6              
7             # 6.2 HEADERS
8             sub decode {
9 30     30 0 5435 my ( $con, $buf_ref, $buf_offset, $length ) = @_;
10 30         5544 my ( $pad, $offset, $weight, $exclusive, $stream_dep ) = ( 0, 0 );
11 30         5471 my $frame_ref = $con->decode_context->{frame};
12              
13             # Protocol errors
14 30 50       5461 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 30 50       5491 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 30 100       5523 if ( $frame_ref->{flags} & PRIORITY_FLAG ) {
29 1         4 ( $stream_dep, $weight ) =
30             unpack( 'NC', substr( $$buf_ref, $buf_offset + $offset, 5 ) );
31 1         2 $exclusive = $stream_dep >> 31;
32 1         1 $stream_dep &= 0x7FFF_FFFF;
33 1         2 $weight++;
34              
35 1         7 $con->stream_weight( $frame_ref->{stream}, $weight );
36 1         4 $con->stream_reprio( $frame_ref->{stream}, $exclusive, $stream_dep, );
37              
38 1         2 $offset += 5;
39             }
40              
41             # Not enough space for header block
42 30         5417 my $hblock_size = $length - $offset - $pad;
43 30 50       5491 if ( $hblock_size < 0 ) {
44 0         0 $con->error(FRAME_SIZE_ERROR);
45 0         0 return undef;
46             }
47              
48             $con->stream_header_block( $frame_ref->{stream},
49 30         5741 substr( $$buf_ref, $buf_offset + $offset, $hblock_size ) );
50              
51             # Stream header block complete
52             $con->stream_headers_done( $frame_ref->{stream} )
53             or return undef
54 30 50 50     5633 if $frame_ref->{flags} & END_HEADERS;
55              
56 30         10943 return $length;
57             }
58              
59             sub encode {
60 33     33 0 6142 my ( $con, $flags_ref, $stream, $data_ref ) = @_;
61 33         5463 my $res = '';
62              
63 33 50       5528 if ( exists $data_ref->{padding} ) {
64 0         0 $$flags_ref |= PADDED;
65 0         0 $res .= pack 'C', $data_ref->{padding};
66             }
67              
68 33 100 66     5676 if ( exists $data_ref->{stream_dep} || exists $data_ref->{weight} ) {
69 1         3 $$flags_ref |= PRIORITY_FLAG;
70 1   50     4 my $weight = ( $data_ref->{weight} || DEFAULT_WEIGHT ) - 1;
71 1   50     6 my $stream_dep = $data_ref->{stream_dep} || 0;
72 1 50       3 $stream_dep |= ( 1 << 31 ) if $data_ref->{exclusive};
73 1         4 $res .= pack 'NC', $stream_dep, $weight;
74             }
75              
76 33         5429 return $res . ${ $data_ref->{hblock} };
  33         16288  
77             }
78              
79             1;