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