xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/adapter/header_validator_base.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #ifndef QUICHE_HTTP2_ADAPTER_HEADER_VALIDATOR_BASE_H_
2 #define QUICHE_HTTP2_ADAPTER_HEADER_VALIDATOR_BASE_H_
3 
4 #include <cstddef>
5 #include <cstdint>
6 #include <optional>
7 #include <string>
8 
9 #include "absl/strings/string_view.h"
10 #include "quiche/common/platform/api/quiche_export.h"
11 
12 namespace http2 {
13 namespace adapter {
14 
15 enum class HeaderType : uint8_t {
16   REQUEST,
17   REQUEST_TRAILER,
18   RESPONSE_100,
19   RESPONSE,
20   RESPONSE_TRAILER,
21 };
22 
23 enum class ObsTextOption : uint8_t {
24   kAllow,
25   kDisallow,
26 };
27 
28 class QUICHE_EXPORT HeaderValidatorBase {
29  public:
30   HeaderValidatorBase() = default;
31   virtual ~HeaderValidatorBase() = default;
32 
StartHeaderBlock()33   virtual void StartHeaderBlock() {
34     status_.clear();
35     content_length_ = std::nullopt;
36   }
37 
38   enum HeaderStatus {
39     HEADER_OK,
40     HEADER_SKIP,
41     HEADER_FIELD_INVALID,
42     HEADER_FIELD_TOO_LONG,
43   };
44   virtual HeaderStatus ValidateSingleHeader(absl::string_view key,
45                                             absl::string_view value) = 0;
46 
47   // Should return true if validation was successful.
48   virtual bool FinishHeaderBlock(HeaderType type) = 0;
49 
50   // For responses, returns the value of the ":status" header, if present.
status_header()51   absl::string_view status_header() const { return status_; }
52 
content_length()53   std::optional<size_t> content_length() const { return content_length_; }
54 
SetMaxFieldSize(uint32_t field_size)55   void SetMaxFieldSize(uint32_t field_size) { max_field_size_ = field_size; }
SetObsTextOption(ObsTextOption option)56   void SetObsTextOption(ObsTextOption option) { obs_text_option_ = option; }
57   // Allows the "extended CONNECT" syntax described in RFC 8441.
SetAllowExtendedConnect()58   void SetAllowExtendedConnect() { allow_extended_connect_ = true; }
SetValidatePath()59   void SetValidatePath() { validate_path_ = true; }
SetAllowFragmentInPath()60   void SetAllowFragmentInPath() { allow_fragment_in_path_ = true; }
SetAllowDifferentHostAndAuthority()61   void SetAllowDifferentHostAndAuthority() {
62     allow_different_host_and_authority_ = true;
63   }
64   // If set, allow uppercase characters in header names (except for
65   // pseudo-headers), in violation with RFC 9113 and RFC 9114.
66   // Default behavior is to enforce that header names are lowercase.
SetAllowUppercaseInHeaderNames()67   void SetAllowUppercaseInHeaderNames() {
68     allow_uppercase_in_header_names_ = true;
69   }
70 
71  protected:
72   std::string status_;
73   std::optional<size_t> max_field_size_;
74   std::optional<size_t> content_length_;
75   ObsTextOption obs_text_option_ = ObsTextOption::kDisallow;
76   bool allow_extended_connect_ = false;
77   bool validate_path_ = false;
78   bool allow_fragment_in_path_ = false;
79   bool allow_different_host_and_authority_ = false;
80   bool allow_uppercase_in_header_names_ = false;
81 };
82 
83 }  // namespace adapter
84 }  // namespace http2
85 
86 #endif  // QUICHE_HTTP2_ADAPTER_HEADER_VALIDATOR_BASE_H_
87