1package Protocol::HTTP2::Frame::Window_update;
2use strict;
3use warnings;
4use Protocol::HTTP2::Constants qw(:flags :errors :limits);
5use Protocol::HTTP2::Trace qw(tracer);
6
7sub decode {
8    my ( $con, $buf_ref, $buf_offset, $length ) = @_;
9    my $frame_ref = $con->decode_context->{frame};
10
11    if ( $length != 4 ) {
12        tracer->error(
13            "Received windows_update frame with invalid length $length");
14        $con->error(FRAME_SIZE_ERROR);
15        return undef;
16    }
17
18    my $fcw_add = unpack 'N', substr $$buf_ref, $buf_offset, 4;
19    $fcw_add &= 0x7FFF_FFFF;
20
21    if ( $fcw_add == 0 ) {
22        tracer->error("Received flow-control window increment of 0");
23        $con->error(PROTOCOL_ERROR);
24        return undef;
25    }
26
27    if ( $frame_ref->{stream} == 0 ) {
28        if ( $con->fcw_send($fcw_add) > MAX_FCW_SIZE ) {
29            $con->error(FLOW_CONTROL_ERROR);
30        }
31        else {
32            $con->send_blocked();
33        }
34    }
35    else {
36        my $fcw = $con->stream_fcw_send( $frame_ref->{stream}, $fcw_add );
37        if ( defined $fcw && $fcw > MAX_FCW_SIZE ) {
38            tracer->warning("flow-control window size exceeded MAX_FCW_SIZE");
39            $con->stream_error( $frame_ref->{stream}, FLOW_CONTROL_ERROR );
40        }
41        elsif ( defined $fcw ) {
42            $con->stream_send_blocked( $frame_ref->{stream} );
43        }
44    }
45    return $length;
46}
47
48sub encode {
49    my ( $con, $flags_ref, $stream, $data ) = @_;
50    return pack 'N', $data;
51}
52
531;
54