#include "quiche/http2/adapter/header_validator.h"

#include <utility>
#include <vector>

#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
#include "quiche/common/platform/api/quiche_test.h"

namespace http2 {
namespace adapter {
namespace test {

using ::testing::Optional;

using Header = std::pair<absl::string_view, absl::string_view>;
constexpr Header kSampleRequestPseudoheaders[] = {{":authority", "www.foo.com"},
                                                  {":method", "GET"},
                                                  {":path", "/foo"},
                                                  {":scheme", "https"}};

TEST(HeaderValidatorTest, HeaderNameEmpty) {
  HeaderValidator v;
  HeaderValidator::HeaderStatus status = v.ValidateSingleHeader("", "value");
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
}

TEST(HeaderValidatorTest, HeaderValueEmpty) {
  HeaderValidator v;
  HeaderValidator::HeaderStatus status = v.ValidateSingleHeader("name", "");
  EXPECT_EQ(HeaderValidator::HEADER_OK, status);
}

TEST(HeaderValidatorTest, ExceedsMaxSize) {
  HeaderValidator v;
  v.SetMaxFieldSize(64u);
  HeaderValidator::HeaderStatus status =
      v.ValidateSingleHeader("name", "value");
  EXPECT_EQ(HeaderValidator::HEADER_OK, status);
  status = v.ValidateSingleHeader(
      "name2",
      "Antidisestablishmentariansism is supercalifragilisticexpialodocious.");
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_TOO_LONG, status);
}

TEST(HeaderValidatorTest, NameHasInvalidChar) {
  HeaderValidator v;
  for (const bool is_pseudo_header : {true, false}) {
    // These characters should be allowed. (Not exhaustive.)
    for (const char* c : {"!", "3", "a", "_", "|", "~"}) {
      const std::string name = is_pseudo_header ? absl::StrCat(":met", c, "hod")
                                                : absl::StrCat("na", c, "me");
      HeaderValidator::HeaderStatus status =
          v.ValidateSingleHeader(name, "value");
      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
    }
    // These should not. (Not exhaustive.)
    for (const char* c : {"\\", "<", ";", "[", "=", " ", "\r", "\n", ",", "\"",
                          "\x1F", "\x91"}) {
      const std::string name = is_pseudo_header ? absl::StrCat(":met", c, "hod")
                                                : absl::StrCat("na", c, "me");
      HeaderValidator::HeaderStatus status =
          v.ValidateSingleHeader(name, "value");
      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
    }
    // Test nul separately.
    {
      const absl::string_view name = is_pseudo_header
                                         ? absl::string_view(":met\0hod", 8)
                                         : absl::string_view("na\0me", 5);
      HeaderValidator::HeaderStatus status =
          v.ValidateSingleHeader(name, "value");
      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
    }
    // Uppercase characters in header names should not be allowed.
    const std::string uc_name = is_pseudo_header ? ":Method" : "Name";
    HeaderValidator::HeaderStatus status =
        v.ValidateSingleHeader(uc_name, "value");
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
  }
}

TEST(HeaderValidatorTest, ValueHasInvalidChar) {
  HeaderValidator v;
  // These characters should be allowed. (Not exhaustive.)
  for (const char* c :
       {"!", "3", "a", "_", "|", "~", "\\", "<", ";", "[", "=", "A", "\t"}) {
    const std::string value = absl::StrCat("val", c, "ue");
    EXPECT_TRUE(
        HeaderValidator::IsValidHeaderValue(value, ObsTextOption::kDisallow));
    HeaderValidator::HeaderStatus status =
        v.ValidateSingleHeader("name", value);
    EXPECT_EQ(HeaderValidator::HEADER_OK, status);
  }
  // These should not.
  for (const char* c : {"\r", "\n"}) {
    const std::string value = absl::StrCat("val", c, "ue");
    EXPECT_FALSE(
        HeaderValidator::IsValidHeaderValue(value, ObsTextOption::kDisallow));
    HeaderValidator::HeaderStatus status =
        v.ValidateSingleHeader("name", value);
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
  }
  // Test nul separately.
  {
    const std::string value("val\0ue", 6);
    EXPECT_FALSE(
        HeaderValidator::IsValidHeaderValue(value, ObsTextOption::kDisallow));
    HeaderValidator::HeaderStatus status =
        v.ValidateSingleHeader("name", value);
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
  }
  {
    const std::string obs_text_value = "val\xa9ue";
    // Test that obs-text is disallowed by default.
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
              v.ValidateSingleHeader("name", obs_text_value));
    // Test that obs-text is disallowed when configured.
    v.SetObsTextOption(ObsTextOption::kDisallow);
    EXPECT_FALSE(HeaderValidator::IsValidHeaderValue(obs_text_value,
                                                     ObsTextOption::kDisallow));
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
              v.ValidateSingleHeader("name", obs_text_value));
    // Test that obs-text is allowed when configured.
    v.SetObsTextOption(ObsTextOption::kAllow);
    EXPECT_TRUE(HeaderValidator::IsValidHeaderValue(obs_text_value,
                                                    ObsTextOption::kAllow));
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader("name", obs_text_value));
  }
}

TEST(HeaderValidatorTest, StatusHasInvalidChar) {
  HeaderValidator v;

  for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
    // When `:status` has a non-digit value, validation will fail.
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
              v.ValidateSingleHeader(":status", "bar"));
    EXPECT_FALSE(v.FinishHeaderBlock(type));

    // When `:status` is too short, validation will fail.
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
              v.ValidateSingleHeader(":status", "10"));
    EXPECT_FALSE(v.FinishHeaderBlock(type));

    // When `:status` is too long, validation will fail.
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
              v.ValidateSingleHeader(":status", "9000"));
    EXPECT_FALSE(v.FinishHeaderBlock(type));

    // When `:status` is just right, validation will succeed.
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "400"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));
  }
}

TEST(HeaderValidatorTest, AuthorityHasInvalidChar) {
  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, 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, 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, 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, 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, value2);
      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
    }

    {
      // Empty field
      EXPECT_TRUE(HeaderValidator::IsValidAuthority(""));

      HeaderValidator v;
      v.StartHeaderBlock();
      HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(key, "");
      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
    }
  }
}

TEST(HeaderValidatorTest, RequestHostAndAuthority) {
  HeaderValidator v;
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  // If both "host" and ":authority" have the same value, validation succeeds.
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("host", "www.foo.com"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  // If "host" and ":authority" have different values, validation fails.
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
            v.ValidateSingleHeader("host", "www.bar.com"));
}

TEST(HeaderValidatorTest, MethodHasInvalidChar) {
  HeaderValidator v;
  v.StartHeaderBlock();

  std::vector<absl::string_view> bad_methods = {
      "In[]valid{}",   "co,mma", "spac e",     "a@t",    "equals=",
      "question?mark", "co:lon", "semi;colon", "sla/sh", "back\\slash",
  };

  std::vector<absl::string_view> good_methods = {
      "lowercase",   "MiXeDcAsE", "NONCANONICAL", "HASH#",
      "under_score", "PI|PE",     "Tilde~",       "quote'",
  };

  for (absl::string_view value : bad_methods) {
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
              v.ValidateSingleHeader(":method", value));
  }

  for (absl::string_view value : good_methods) {
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":method", value));
    for (Header to_add : kSampleRequestPseudoheaders) {
      if (to_add.first == ":method") {
        continue;
      }
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
    EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
  }
}

TEST(HeaderValidatorTest, RequestPseudoHeaders) {
  HeaderValidator v;
  for (Header to_skip : kSampleRequestPseudoheaders) {
    v.StartHeaderBlock();
    for (Header to_add : kSampleRequestPseudoheaders) {
      if (to_add != to_skip) {
        EXPECT_EQ(HeaderValidator::HEADER_OK,
                  v.ValidateSingleHeader(to_add.first, to_add.second));
      }
    }
    // When any pseudo-header is missing, final validation will fail.
    EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
  }

  // When all pseudo-headers are present, final validation will succeed.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // When an extra pseudo-header is present, final validation will fail.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":extra", "blah"));
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // When a required pseudo-header is repeated, final validation will fail.
  for (Header to_repeat : kSampleRequestPseudoheaders) {
    v.StartHeaderBlock();
    for (Header to_add : kSampleRequestPseudoheaders) {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
      if (to_add == to_repeat) {
        EXPECT_EQ(HeaderValidator::HEADER_OK,
                  v.ValidateSingleHeader(to_add.first, to_add.second));
      }
    }
    EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
  }
}

TEST(HeaderValidatorTest, ConnectHeaders) {
  // Too few headers.
  HeaderValidator v;
  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":authority", "athena.dialup.mit.edu:23"));
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":method", "CONNECT"));
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // Too many headers.
  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":authority", "athena.dialup.mit.edu:23"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":method", "CONNECT"));
  EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader(":path", "/"));
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // Empty :authority
  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":authority", ""));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":method", "CONNECT"));
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // Just right.
  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":authority", "athena.dialup.mit.edu:23"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":method", "CONNECT"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  v.SetAllowExtendedConnect();
  // "Classic" CONNECT headers should still be accepted.
  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":authority", "athena.dialup.mit.edu:23"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":method", "CONNECT"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
}

TEST(HeaderValidatorTest, WebsocketPseudoHeaders) {
  HeaderValidator v;
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":protocol", "websocket"));
  // At this point, `:protocol` is treated as an extra pseudo-header.
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // Future header blocks may send the `:protocol` pseudo-header for CONNECT
  // requests.
  v.SetAllowExtendedConnect();

  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":protocol", "websocket"));
  // The method is not "CONNECT", so `:protocol` is still treated as an extra
  // pseudo-header.
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":method") {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "CONNECT"));
    } else {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":protocol", "websocket"));
  // After allowing the method, `:protocol` is acepted for CONNECT requests.
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
}

TEST(HeaderValidatorTest, AsteriskPathPseudoHeader) {
  HeaderValidator v;

  // An asterisk :path should not be allowed for non-OPTIONS requests.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":path") {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "*"));
    } else {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // An asterisk :path should be allowed for OPTIONS requests.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":path") {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "*"));
    } else if (to_add.first == ":method") {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "OPTIONS"));
    } else {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
}

TEST(HeaderValidatorTest, InvalidPathPseudoHeader) {
  HeaderValidator v;

  // An empty path should fail on single header validation and finish.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":path") {
      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
                v.ValidateSingleHeader(to_add.first, ""));
    } else {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // A path that does not start with a slash should fail on finish.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":path") {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "shawarma"));
    } else {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // Various valid path characters.
  for (const absl::string_view c :
       {"/", "?", "_", "'", "9", "&", "(", "@", ":"}) {
    const std::string value = absl::StrCat("/shawa", c, "rma");

    HeaderValidator validator;
    validator.StartHeaderBlock();
    for (Header to_add : kSampleRequestPseudoheaders) {
      if (to_add.first == ":path") {
        EXPECT_EQ(HeaderValidator::HEADER_OK,
                  validator.ValidateSingleHeader(to_add.first, value));
      } else {
        EXPECT_EQ(HeaderValidator::HEADER_OK,
                  validator.ValidateSingleHeader(to_add.first, to_add.second));
      }
    }
    EXPECT_TRUE(validator.FinishHeaderBlock(HeaderType::REQUEST));
  }

  // BUG: Various invalid path characters.
  for (const absl::string_view c : {"[", "<", "}", "`", "\\", " ", "\t"}) {
    const std::string value = absl::StrCat("/shawa", c, "rma");

    HeaderValidator validator;
    validator.StartHeaderBlock();
    for (Header to_add : kSampleRequestPseudoheaders) {
      if (to_add.first == ":path") {
        EXPECT_EQ(HeaderValidator::HEADER_OK,
                  validator.ValidateSingleHeader(to_add.first, value));
      } else {
        EXPECT_EQ(HeaderValidator::HEADER_OK,
                  validator.ValidateSingleHeader(to_add.first, to_add.second));
      }
    }
    EXPECT_TRUE(validator.FinishHeaderBlock(HeaderType::REQUEST));
  }
}

TEST(HeaderValidatorTest, ResponsePseudoHeaders) {
  HeaderValidator v;

  for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
    // When `:status` is missing, validation will fail.
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader("foo", "bar"));
    EXPECT_FALSE(v.FinishHeaderBlock(type));

    // When all pseudo-headers are present, final validation will succeed.
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "199"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));
    EXPECT_EQ("199", v.status_header());

    // When `:status` is repeated, validation will fail.
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "199"));
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "299"));
    EXPECT_FALSE(v.FinishHeaderBlock(type));

    // When an extra pseudo-header is present, final validation will fail.
    v.StartHeaderBlock();
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "199"));
    EXPECT_EQ(HeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":extra", "blorp"));
    EXPECT_FALSE(v.FinishHeaderBlock(type));
  }
}

TEST(HeaderValidatorTest, ResponseWithHost) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "200"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("host", "myserver.com"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(HeaderValidatorTest, Response204) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "204"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(HeaderValidatorTest, ResponseWithMultipleIdenticalContentLength) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "200"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "13"));
  EXPECT_EQ(HeaderValidator::HEADER_SKIP,
            v.ValidateSingleHeader("content-length", "13"));
}

TEST(HeaderValidatorTest, ResponseWithMultipleDifferingContentLength) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "200"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "13"));
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
            v.ValidateSingleHeader("content-length", "17"));
}

TEST(HeaderValidatorTest, Response204WithContentLengthZero) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "204"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "0"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(HeaderValidatorTest, Response204WithContentLength) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "204"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
            v.ValidateSingleHeader("content-length", "1"));
}

TEST(HeaderValidatorTest, Response100) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "100"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(HeaderValidatorTest, Response100WithContentLengthZero) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "100"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "0"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(HeaderValidatorTest, Response100WithContentLength) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "100"));
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
            v.ValidateSingleHeader("content-length", "1"));
}

TEST(HeaderValidatorTest, ResponseTrailerPseudoHeaders) {
  HeaderValidator v;

  // When no pseudo-headers are present, validation will succeed.
  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader("foo", "bar"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));

  // When any pseudo-header is present, final validation will fail.
  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "200"));
  EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader("foo", "bar"));
  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));
}

TEST(HeaderValidatorTest, ValidContentLength) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "41"));
  EXPECT_THAT(v.content_length(), Optional(41));

  v.StartHeaderBlock();
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "42"));
  EXPECT_THAT(v.content_length(), Optional(42));
}

TEST(HeaderValidatorTest, InvalidContentLength) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
            v.ValidateSingleHeader("content-length", ""));
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
            v.ValidateSingleHeader("content-length", "nan"));
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
            v.ValidateSingleHeader("content-length", "-42"));
  EXPECT_EQ(v.content_length(), absl::nullopt);
  // End on a positive note.
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "42"));
  EXPECT_THAT(v.content_length(), Optional(42));
}

TEST(HeaderValidatorTest, TeHeader) {
  HeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("te", "trailers"));

  v.StartHeaderBlock();
  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
            v.ValidateSingleHeader("te", "trailers, deflate"));
}

TEST(HeaderValidatorTest, ConnectionSpecificHeaders) {
  const std::vector<Header> connection_headers = {
      {"connection", "keep-alive"}, {"proxy-connection", "keep-alive"},
      {"keep-alive", "timeout=42"}, {"transfer-encoding", "chunked"},
      {"upgrade", "h2c"},
  };
  for (const auto& [connection_key, connection_value] : connection_headers) {
    HeaderValidator v;
    v.StartHeaderBlock();
    for (const auto& [sample_key, sample_value] : kSampleRequestPseudoheaders) {
      EXPECT_EQ(HeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(sample_key, sample_value));
    }
    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
              v.ValidateSingleHeader(connection_key, connection_value));
  }
}

}  // namespace test
}  // namespace adapter
}  // namespace http2
