123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef NET_SPDY_ALPS_DECODER_H_
- #define NET_SPDY_ALPS_DECODER_H_
- #include <cstddef>
- #include "base/containers/span.h"
- #include "base/strings/string_number_conversions.h"
- #include "net/base/net_export.h"
- #include "net/third_party/quiche/src/quiche/spdy/core/http2_frame_decoder_adapter.h"
- #include "net/third_party/quiche/src/quiche/spdy/core/spdy_no_op_visitor.h"
- #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
- namespace net {
- // Class to parse HTTP/2 frames in the extension_data field
- // of the ALPS TLS extension.
- class NET_EXPORT_PRIVATE AlpsDecoder {
- public:
- // These values are persisted to logs. Entries should not be renumbered, and
- // numeric values should never be reused.
- enum class Error {
- // No error has occurred.
- kNoError = 0,
- // HTTP/2 framing error detected by Http2DecoderAdapter.
- kFramingError = 1,
- // Forbidden HTTP/2 frame received.
- kForbiddenFrame = 2,
- // Input does not end on HTTP/2 frame boundary.
- kNotOnFrameBoundary = 3,
- // SETTINGS frame with ACK received.
- kSettingsWithAck = 4,
- // ACCEPT_CH received on invalid stream.
- kAcceptChInvalidStream = 5,
- // ACCEPT_CH received with flags.
- kAcceptChWithFlags = 6,
- // Malformed ACCEPT_CH payload.
- kAcceptChMalformed = 7,
- kMaxValue = kAcceptChMalformed
- };
- AlpsDecoder();
- ~AlpsDecoder();
- // Decode a stream of HTTP/2 frames received via the ALPS TLS extension.
- // The HTTP/2 connection preface MUST NOT be present in the input.
- // Frames other than SETTINGS and ACCEPT_CH are ignored other than for the
- // purposes of enforcing HTTP/2 framing rules.
- // May only be called once, with the entire ALPS extension_data.
- // Returns an error code, or Error::kNoError if no error has occurred.
- // The requirement that the first frame MUST be SETTINGS is not enforced,
- // because that only applies to HTTP/2 connections, not ALPS data.
- [[nodiscard]] Error Decode(base::span<const char> data);
- // The number of SETTINGS frames received.
- int settings_frame_count() const;
- // The HTTP/2 setting parameters parsed from |data|.
- const spdy::SettingsMap& GetSettings() const {
- return settings_parser_.GetSettings();
- }
- // Origins and corresponding Accept-CH values parsed from |data|. See
- // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
- const std::vector<spdy::AcceptChOriginValuePair>& GetAcceptCh() const {
- return accept_ch_parser_.GetAcceptCh();
- }
- private:
- class SettingsParser : public spdy::SpdyNoOpVisitor {
- public:
- SettingsParser();
- ~SettingsParser() override;
- bool forbidden_frame_received() const { return forbidden_frame_received_; }
- bool settings_ack_received() const { return settings_ack_received_; }
- int settings_frame_count() const { return settings_frame_count_; }
- // Number of SETTINGS frames received.
- const spdy::SettingsMap& GetSettings() const { return settings_; }
- // SpdyFramerVisitorInterface overrides.
- void OnCommonHeader(spdy::SpdyStreamId stream_id,
- size_t length,
- uint8_t type,
- uint8_t flags) override;
- void OnSettings() override;
- void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
- void OnSettingsAck() override;
- private:
- // True if a forbidden HTTP/2 frame has been received.
- bool forbidden_frame_received_ = false;
- // True if a SETTINGS frame with ACK flag has been received.
- bool settings_ack_received_ = false;
- // Number of SETTINGS frames received.
- int settings_frame_count_ = 0;
- // Accumulated setting parameters.
- spdy::SettingsMap settings_;
- };
- // Class to parse ACCEPT_CH frames.
- class AcceptChParser : public spdy::ExtensionVisitorInterface {
- public:
- AcceptChParser();
- ~AcceptChParser() override;
- const std::vector<spdy::AcceptChOriginValuePair>& GetAcceptCh() const {
- return accept_ch_;
- }
- // Returns an error code, or Error::kNoError if no error has occurred.
- Error error() const { return error_; }
- // ExtensionVisitorInterface implementation.
- // Settings are parsed in a SpdyFramerVisitorInterface implementation,
- // because ExtensionVisitorInterface does not provide information about
- // receiving an empty SETTINGS frame.
- void OnSetting(spdy::SpdySettingsId id, uint32_t value) override {}
- bool OnFrameHeader(spdy::SpdyStreamId stream_id,
- size_t length,
- uint8_t type,
- uint8_t flags) override;
- void OnFramePayload(const char* data, size_t len) override;
- private:
- // Accumulated ACCEPT_CH values.
- std::vector<spdy::AcceptChOriginValuePair> accept_ch_;
- Error error_ = Error::kNoError;
- };
- SettingsParser settings_parser_;
- AcceptChParser accept_ch_parser_;
- http2::Http2DecoderAdapter decoder_adapter_;
- };
- } // namespace net
- #endif // NET_SPDY_ALPS_DECODER_H_
|