Extracts out authority validation into a separate static method.
This can then be used as a replacement for a similar function in nghttp2.
PiperOrigin-RevId: 500812383
diff --git a/quiche/http2/adapter/header_validator.cc b/quiche/http2/adapter/header_validator.cc
index 67d543a..e4874f2 100644
--- a/quiche/http2/adapter/header_validator.cc
+++ b/quiche/http2/adapter/header_validator.cc
@@ -246,6 +246,12 @@
return false;
}
+/* static */
+bool HeaderValidator::IsValidAuthority(absl::string_view authority) {
+ static const CharMap valid_chars = BuildValidCharMap(kValidAuthorityChars);
+ return AllCharsInMap(authority, valid_chars);
+}
+
HeaderValidator::ContentLengthStatus HeaderValidator::HandleContentLength(
absl::string_view value) {
if (value.empty()) {
@@ -278,8 +284,7 @@
// Returns whether `authority` contains only characters from the `host` ABNF
// from RFC 3986 section 3.2.2.
bool HeaderValidator::ValidateAndSetAuthority(absl::string_view authority) {
- static const CharMap valid_chars = BuildValidCharMap(kValidAuthorityChars);
- if (!AllCharsInMap(authority, valid_chars)) {
+ if (!IsValidAuthority(authority)) {
return false;
}
if (authority_.has_value() && authority != authority_.value()) {
diff --git a/quiche/http2/adapter/header_validator.h b/quiche/http2/adapter/header_validator.h
index 096f76f..6095c7d 100644
--- a/quiche/http2/adapter/header_validator.h
+++ b/quiche/http2/adapter/header_validator.h
@@ -25,6 +25,9 @@
// present for the given header type.
bool FinishHeaderBlock(HeaderType type) override;
+ // Returns whether `authority` is valid according to RFC 3986 Section 3.2.
+ static bool IsValidAuthority(absl::string_view authority);
+
private:
enum ContentLengthStatus {
CONTENT_LENGTH_OK,
diff --git a/quiche/http2/adapter/header_validator_test.cc b/quiche/http2/adapter/header_validator_test.cc
index 6e446f2..a329f12 100644
--- a/quiche/http2/adapter/header_validator_test.cc
+++ b/quiche/http2/adapter/header_validator_test.cc
@@ -150,45 +150,59 @@
for (absl::string_view key : {":authority", "host"}) {
// These characters should be allowed. (Not exhaustive.)
for (const absl::string_view c : {"1", "-", "!", ":", "+", "=", ","}) {
+ const std::string value = absl::StrCat("ho", c, "st.example.com");
+ EXPECT_TRUE(HeaderValidator::IsValidAuthority(value));
+
HeaderValidator v;
v.StartHeaderBlock();
- HeaderValidator::HeaderStatus status =
- v.ValidateSingleHeader(key, absl::StrCat("ho", c, "st.example.com"));
+ HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(key, value);
EXPECT_EQ(HeaderValidator::HEADER_OK, status);
}
// These should not.
for (const absl::string_view c : {"\r", "\n", "|", "\\", "`"}) {
+ const std::string value = absl::StrCat("ho", c, "st.example.com");
+ EXPECT_FALSE(HeaderValidator::IsValidAuthority(value));
+
HeaderValidator v;
v.StartHeaderBlock();
- HeaderValidator::HeaderStatus status =
- v.ValidateSingleHeader(key, absl::StrCat("ho", c, "st.example.com"));
+ HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(key, value);
EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
}
{
// IPv4 example
+ const std::string value = "123.45.67.89";
+ EXPECT_TRUE(HeaderValidator::IsValidAuthority(value));
+
HeaderValidator v;
v.StartHeaderBlock();
- HeaderValidator::HeaderStatus status =
- v.ValidateSingleHeader(key, "123.45.67.89");
+ HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(key, value);
EXPECT_EQ(HeaderValidator::HEADER_OK, status);
}
{
// IPv6 examples
+ const std::string value1 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
+ EXPECT_TRUE(HeaderValidator::IsValidAuthority(value1));
+
HeaderValidator v;
v.StartHeaderBlock();
- HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(
- key, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+ HeaderValidator::HeaderStatus status =
+ v.ValidateSingleHeader(key, value1);
EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+
+ const std::string value2 = "[::1]:80";
+ EXPECT_TRUE(HeaderValidator::IsValidAuthority(value2));
HeaderValidator v2;
v2.StartHeaderBlock();
- status = v2.ValidateSingleHeader(key, "[::1]:80");
+ status = v2.ValidateSingleHeader(key, value2);
EXPECT_EQ(HeaderValidator::HEADER_OK, status);
}
{
// Empty field
+ EXPECT_TRUE(HeaderValidator::IsValidAuthority(""));
+
HeaderValidator v;
v.StartHeaderBlock();
HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(key, "");