blob: a04179288678fcc1c8f772da11b3cff6c6b0760d [file] [log] [blame]
QUICHE teamfd50a402018-12-07 22:54:05 -05001// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "http2/decoder/payload_decoders/settings_payload_decoder.h"
QUICHE teamfd50a402018-12-07 22:54:05 -05006
QUICHE team5be974e2020-12-29 18:35:24 -05007#include "http2/decoder/decode_buffer.h"
8#include "http2/decoder/http2_frame_decoder_listener.h"
9#include "http2/http2_constants.h"
10#include "http2/http2_structures.h"
11#include "http2/platform/api/http2_logging.h"
QUICHE teamfd50a402018-12-07 22:54:05 -050012
13namespace http2 {
14
15DecodeStatus SettingsPayloadDecoder::StartDecodingPayload(
16 FrameDecoderState* state,
17 DecodeBuffer* db) {
18 const Http2FrameHeader& frame_header = state->frame_header();
19 const uint32_t total_length = frame_header.payload_length;
20
QUICHE team61940b42019-03-07 23:32:27 -050021 HTTP2_DVLOG(2) << "SettingsPayloadDecoder::StartDecodingPayload: "
22 << frame_header;
vasilvvafcc3172021-02-02 12:01:07 -080023 QUICHE_DCHECK_EQ(Http2FrameType::SETTINGS, frame_header.type);
24 QUICHE_DCHECK_LE(db->Remaining(), total_length);
25 QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::ACK));
QUICHE teamfd50a402018-12-07 22:54:05 -050026
27 if (frame_header.IsAck()) {
28 if (total_length == 0) {
29 state->listener()->OnSettingsAck(frame_header);
30 return DecodeStatus::kDecodeDone;
31 } else {
32 state->InitializeRemainders();
33 return state->ReportFrameSizeError();
34 }
35 } else {
36 state->InitializeRemainders();
37 state->listener()->OnSettingsStart(frame_header);
38 return StartDecodingSettings(state, db);
39 }
40}
41
42DecodeStatus SettingsPayloadDecoder::ResumeDecodingPayload(
43 FrameDecoderState* state,
44 DecodeBuffer* db) {
QUICHE team61940b42019-03-07 23:32:27 -050045 HTTP2_DVLOG(2) << "SettingsPayloadDecoder::ResumeDecodingPayload"
46 << " remaining_payload=" << state->remaining_payload()
47 << " db->Remaining=" << db->Remaining();
vasilvvafcc3172021-02-02 12:01:07 -080048 QUICHE_DCHECK_EQ(Http2FrameType::SETTINGS, state->frame_header().type);
49 QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
QUICHE teamfd50a402018-12-07 22:54:05 -050050
51 DecodeStatus status =
52 state->ResumeDecodingStructureInPayload(&setting_fields_, db);
53 if (status == DecodeStatus::kDecodeDone) {
54 state->listener()->OnSetting(setting_fields_);
55 return StartDecodingSettings(state, db);
56 }
57 return HandleNotDone(state, db, status);
58}
59
60DecodeStatus SettingsPayloadDecoder::StartDecodingSettings(
61 FrameDecoderState* state,
62 DecodeBuffer* db) {
QUICHE team61940b42019-03-07 23:32:27 -050063 HTTP2_DVLOG(2) << "SettingsPayloadDecoder::StartDecodingSettings"
64 << " remaining_payload=" << state->remaining_payload()
65 << " db->Remaining=" << db->Remaining();
QUICHE teamfd50a402018-12-07 22:54:05 -050066 while (state->remaining_payload() > 0) {
67 DecodeStatus status =
68 state->StartDecodingStructureInPayload(&setting_fields_, db);
69 if (status == DecodeStatus::kDecodeDone) {
70 state->listener()->OnSetting(setting_fields_);
71 continue;
72 }
73 return HandleNotDone(state, db, status);
74 }
QUICHE team61940b42019-03-07 23:32:27 -050075 HTTP2_DVLOG(2) << "LEAVING SettingsPayloadDecoder::StartDecodingSettings"
76 << "\n\tdb->Remaining=" << db->Remaining()
77 << "\n\t remaining_payload=" << state->remaining_payload();
QUICHE teamfd50a402018-12-07 22:54:05 -050078 state->listener()->OnSettingsEnd();
79 return DecodeStatus::kDecodeDone;
80}
81
82DecodeStatus SettingsPayloadDecoder::HandleNotDone(FrameDecoderState* state,
83 DecodeBuffer* db,
84 DecodeStatus status) {
85 // Not done decoding the structure. Either we've got more payload to decode,
86 // or we've run out because the payload is too short, in which case
87 // OnFrameSizeError will have already been called.
vasilvvafcc3172021-02-02 12:01:07 -080088 QUICHE_DCHECK(
QUICHE teamfd50a402018-12-07 22:54:05 -050089 (status == DecodeStatus::kDecodeInProgress &&
90 state->remaining_payload() > 0) ||
91 (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
92 << "\n status=" << status
93 << "; remaining_payload=" << state->remaining_payload()
94 << "; db->Remaining=" << db->Remaining();
95 return status;
96}
97
98} // namespace http2