alps_decoder.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright 2021 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. #ifndef NET_SPDY_ALPS_DECODER_H_
  5. #define NET_SPDY_ALPS_DECODER_H_
  6. #include <cstddef>
  7. #include "base/containers/span.h"
  8. #include "base/strings/string_number_conversions.h"
  9. #include "net/base/net_export.h"
  10. #include "net/third_party/quiche/src/quiche/spdy/core/http2_frame_decoder_adapter.h"
  11. #include "net/third_party/quiche/src/quiche/spdy/core/spdy_no_op_visitor.h"
  12. #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
  13. namespace net {
  14. // Class to parse HTTP/2 frames in the extension_data field
  15. // of the ALPS TLS extension.
  16. class NET_EXPORT_PRIVATE AlpsDecoder {
  17. public:
  18. // These values are persisted to logs. Entries should not be renumbered, and
  19. // numeric values should never be reused.
  20. enum class Error {
  21. // No error has occurred.
  22. kNoError = 0,
  23. // HTTP/2 framing error detected by Http2DecoderAdapter.
  24. kFramingError = 1,
  25. // Forbidden HTTP/2 frame received.
  26. kForbiddenFrame = 2,
  27. // Input does not end on HTTP/2 frame boundary.
  28. kNotOnFrameBoundary = 3,
  29. // SETTINGS frame with ACK received.
  30. kSettingsWithAck = 4,
  31. // ACCEPT_CH received on invalid stream.
  32. kAcceptChInvalidStream = 5,
  33. // ACCEPT_CH received with flags.
  34. kAcceptChWithFlags = 6,
  35. // Malformed ACCEPT_CH payload.
  36. kAcceptChMalformed = 7,
  37. kMaxValue = kAcceptChMalformed
  38. };
  39. AlpsDecoder();
  40. ~AlpsDecoder();
  41. // Decode a stream of HTTP/2 frames received via the ALPS TLS extension.
  42. // The HTTP/2 connection preface MUST NOT be present in the input.
  43. // Frames other than SETTINGS and ACCEPT_CH are ignored other than for the
  44. // purposes of enforcing HTTP/2 framing rules.
  45. // May only be called once, with the entire ALPS extension_data.
  46. // Returns an error code, or Error::kNoError if no error has occurred.
  47. // The requirement that the first frame MUST be SETTINGS is not enforced,
  48. // because that only applies to HTTP/2 connections, not ALPS data.
  49. [[nodiscard]] Error Decode(base::span<const char> data);
  50. // The number of SETTINGS frames received.
  51. int settings_frame_count() const;
  52. // The HTTP/2 setting parameters parsed from |data|.
  53. const spdy::SettingsMap& GetSettings() const {
  54. return settings_parser_.GetSettings();
  55. }
  56. // Origins and corresponding Accept-CH values parsed from |data|. See
  57. // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
  58. const std::vector<spdy::AcceptChOriginValuePair>& GetAcceptCh() const {
  59. return accept_ch_parser_.GetAcceptCh();
  60. }
  61. private:
  62. class SettingsParser : public spdy::SpdyNoOpVisitor {
  63. public:
  64. SettingsParser();
  65. ~SettingsParser() override;
  66. bool forbidden_frame_received() const { return forbidden_frame_received_; }
  67. bool settings_ack_received() const { return settings_ack_received_; }
  68. int settings_frame_count() const { return settings_frame_count_; }
  69. // Number of SETTINGS frames received.
  70. const spdy::SettingsMap& GetSettings() const { return settings_; }
  71. // SpdyFramerVisitorInterface overrides.
  72. void OnCommonHeader(spdy::SpdyStreamId stream_id,
  73. size_t length,
  74. uint8_t type,
  75. uint8_t flags) override;
  76. void OnSettings() override;
  77. void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
  78. void OnSettingsAck() override;
  79. private:
  80. // True if a forbidden HTTP/2 frame has been received.
  81. bool forbidden_frame_received_ = false;
  82. // True if a SETTINGS frame with ACK flag has been received.
  83. bool settings_ack_received_ = false;
  84. // Number of SETTINGS frames received.
  85. int settings_frame_count_ = 0;
  86. // Accumulated setting parameters.
  87. spdy::SettingsMap settings_;
  88. };
  89. // Class to parse ACCEPT_CH frames.
  90. class AcceptChParser : public spdy::ExtensionVisitorInterface {
  91. public:
  92. AcceptChParser();
  93. ~AcceptChParser() override;
  94. const std::vector<spdy::AcceptChOriginValuePair>& GetAcceptCh() const {
  95. return accept_ch_;
  96. }
  97. // Returns an error code, or Error::kNoError if no error has occurred.
  98. Error error() const { return error_; }
  99. // ExtensionVisitorInterface implementation.
  100. // Settings are parsed in a SpdyFramerVisitorInterface implementation,
  101. // because ExtensionVisitorInterface does not provide information about
  102. // receiving an empty SETTINGS frame.
  103. void OnSetting(spdy::SpdySettingsId id, uint32_t value) override {}
  104. bool OnFrameHeader(spdy::SpdyStreamId stream_id,
  105. size_t length,
  106. uint8_t type,
  107. uint8_t flags) override;
  108. void OnFramePayload(const char* data, size_t len) override;
  109. private:
  110. // Accumulated ACCEPT_CH values.
  111. std::vector<spdy::AcceptChOriginValuePair> accept_ch_;
  112. Error error_ = Error::kNoError;
  113. };
  114. SettingsParser settings_parser_;
  115. AcceptChParser accept_ch_parser_;
  116. http2::Http2DecoderAdapter decoder_adapter_;
  117. };
  118. } // namespace net
  119. #endif // NET_SPDY_ALPS_DECODER_H_