#include "quiche/binary_http/binary_http_message.h"

#include <cstdint>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "quiche/common/platform/api/quiche_test.h"

using ::testing::ContainerEq;
using ::testing::FieldsAre;
using ::testing::StrEq;

namespace quiche {
namespace {

std::string WordToBytes(uint32_t word) {
  return std::string({static_cast<char>(word >> 24),
                      static_cast<char>(word >> 16),
                      static_cast<char>(word >> 8), static_cast<char>(word)});
}

template <class T>
void TestPrintTo(const T& resp) {
  std::ostringstream os;
  PrintTo(resp, &os);
  EXPECT_EQ(os.str(), resp.DebugString());
}
}  // namespace
// Test examples from
// https://www.ietf.org/archive/id/draft-ietf-httpbis-binary-message-06.html

TEST(BinaryHttpRequest, EncodeGetNoBody) {
  /*
    GET /hello.txt HTTP/1.1
    User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
    Host: www.example.com
    Accept-Language: en, mi
  */
  BinaryHttpRequest request({"GET", "https", "www.example.com", "/hello.txt"});
  request
      .AddHeaderField({"User-Agent",
                       "curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3"})
      ->AddHeaderField({"Host", "www.example.com"})
      ->AddHeaderField({"Accept-Language", "en, mi"});
  /*
      00000000: 00034745 54056874 74707300 0a2f6865  ..GET.https../he
      00000010: 6c6c6f2e 74787440 6c0a7573 65722d61  llo.txt@l.user-a
      00000020: 67656e74 34637572 6c2f372e 31362e33  gent4curl/7.16.3
      00000030: 206c6962 6375726c 2f372e31 362e3320   libcurl/7.16.3
      00000040: 4f70656e 53534c2f 302e392e 376c207a  OpenSSL/0.9.7l z
      00000050: 6c69622f 312e322e 3304686f 73740f77  lib/1.2.3.host.w
      00000060: 77772e65 78616d70 6c652e63 6f6d0f61  ww.example.com.a
      00000070: 63636570 742d6c61 6e677561 67650665  ccept-language.e
      00000080: 6e2c206d 6900                        n, mi..
  */
  const uint32_t expected_words[] = {
      0x00034745, 0x54056874, 0x74707300, 0x0a2f6865, 0x6c6c6f2e, 0x74787440,
      0x6c0a7573, 0x65722d61, 0x67656e74, 0x34637572, 0x6c2f372e, 0x31362e33,
      0x206c6962, 0x6375726c, 0x2f372e31, 0x362e3320, 0x4f70656e, 0x53534c2f,
      0x302e392e, 0x376c207a, 0x6c69622f, 0x312e322e, 0x3304686f, 0x73740f77,
      0x77772e65, 0x78616d70, 0x6c652e63, 0x6f6d0f61, 0x63636570, 0x742d6c61,
      0x6e677561, 0x67650665, 0x6e2c206d, 0x69000000};
  std::string expected;
  for (const auto& word : expected_words) {
    expected += WordToBytes(word);
  }
  // Remove padding.
  expected.resize(expected.size() - 2);

  const auto result = request.Serialize();
  ASSERT_TRUE(result.ok());
  ASSERT_EQ(*result, expected);
  EXPECT_THAT(
      request.DebugString(),
      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=curl/"
            "7.16.3 "
            "libcurl/7.16.3 OpenSSL/0.9.7l "
            "zlib/1.2.3};Field{host=www.example.com};Field{accept-language=en, "
            "mi}}Body{}}}"));
  TestPrintTo(request);
}

TEST(BinaryHttpRequest, DecodeGetNoBody) {
  const uint32_t words[] = {
      0x00034745, 0x54056874, 0x74707300, 0x0a2f6865, 0x6c6c6f2e, 0x74787440,
      0x6c0a7573, 0x65722d61, 0x67656e74, 0x34637572, 0x6c2f372e, 0x31362e33,
      0x206c6962, 0x6375726c, 0x2f372e31, 0x362e3320, 0x4f70656e, 0x53534c2f,
      0x302e392e, 0x376c207a, 0x6c69622f, 0x312e322e, 0x3304686f, 0x73740f77,
      0x77772e65, 0x78616d70, 0x6c652e63, 0x6f6d0f61, 0x63636570, 0x742d6c61,
      0x6e677561, 0x67650665, 0x6e2c206d, 0x69000000};
  std::string data;
  for (const auto& word : words) {
    data += WordToBytes(word);
  }

  // Remove all padding
  data.resize(data.size() - 3);

  const auto request_so = BinaryHttpRequest::Create(data);
  ASSERT_TRUE(request_so.ok());
  const BinaryHttpRequest request = *request_so;
  ASSERT_THAT(request.control_data(),
              FieldsAre("GET", "https", "", "/hello.txt"));
  std::vector<BinaryHttpMessage::Field> expected_fields = {
      {"user-agent", "curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3"},
      {"host", "www.example.com"},
      {"accept-language", "en, mi"}};
  for (const auto& field : expected_fields) {
    TestPrintTo(field);
  }
  ASSERT_THAT(request.GetHeaderFields(), ContainerEq(expected_fields));
  ASSERT_EQ(request.body(), "");
  EXPECT_THAT(
      request.DebugString(),
      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=curl/"
            "7.16.3 "
            "libcurl/7.16.3 OpenSSL/0.9.7l "
            "zlib/1.2.3};Field{host=www.example.com};Field{accept-language=en, "
            "mi}}Body{}}}"));
  TestPrintTo(request);
}

TEST(BinaryHttpRequest, EncodeGetWithAuthority) {
  /*
    GET https://www.example.com/hello.txt HTTP/1.1
    User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
    Accept-Language: en, mi
  */
  BinaryHttpRequest request({"GET", "https", "www.example.com", "/hello.txt"});
  request
      .AddHeaderField({"User-Agent",
                       "curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3"})
      ->AddHeaderField({"Accept-Language", "en, mi"});
  /*
    00000000: 00034745 54056874 7470730f 7777772e  ..GET.https.www.
    00000010: 6578616d 706c652e 636f6d0a 2f68656c  example.com./hel
    00000020: 6c6f2e74 78744057 0a757365 722d6167  lo.txt@W.user-ag
    00000030: 656e7434 6375726c 2f372e31 362e3320  ent4curl/7.16.3
    00000040: 6c696263 75726c2f 372e3136 2e33204f  libcurl/7.16.3 O
    00000050: 70656e53 534c2f30 2e392e37 6c207a6c  penSSL/0.9.7l zl
    00000060: 69622f31 2e322e33 0f616363 6570742d  ib/1.2.3.accept-
    00000070: 6c616e67 75616765 06656e2c 206d6900  language.en, mi.
  */

  const uint32_t expected_words[] = {
      0x00034745, 0x54056874, 0x7470730f, 0x7777772e, 0x6578616d, 0x706c652e,
      0x636f6d0a, 0x2f68656c, 0x6c6f2e74, 0x78744057, 0x0a757365, 0x722d6167,
      0x656e7434, 0x6375726c, 0x2f372e31, 0x362e3320, 0x6c696263, 0x75726c2f,
      0x372e3136, 0x2e33204f, 0x70656e53, 0x534c2f30, 0x2e392e37, 0x6c207a6c,
      0x69622f31, 0x2e322e33, 0x0f616363, 0x6570742d, 0x6c616e67, 0x75616765,
      0x06656e2c, 0x206d6900};
  std::string expected;
  for (const auto& word : expected_words) {
    expected += WordToBytes(word);
  }
  const auto result = request.Serialize();
  ASSERT_TRUE(result.ok());
  ASSERT_EQ(*result, expected);
  EXPECT_THAT(
      request.DebugString(),
      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=curl/"
            "7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l "
            "zlib/1.2.3};Field{accept-language=en, mi}}Body{}}}"));
}

TEST(BinaryHttpRequest, DecodeGetWithAuthority) {
  const uint32_t words[] = {
      0x00034745, 0x54056874, 0x7470730f, 0x7777772e, 0x6578616d, 0x706c652e,
      0x636f6d0a, 0x2f68656c, 0x6c6f2e74, 0x78744057, 0x0a757365, 0x722d6167,
      0x656e7434, 0x6375726c, 0x2f372e31, 0x362e3320, 0x6c696263, 0x75726c2f,
      0x372e3136, 0x2e33204f, 0x70656e53, 0x534c2f30, 0x2e392e37, 0x6c207a6c,
      0x69622f31, 0x2e322e33, 0x0f616363, 0x6570742d, 0x6c616e67, 0x75616765,
      0x06656e2c, 0x206d6900, 0x00};
  std::string data;
  for (const auto& word : words) {
    data += WordToBytes(word);
  }
  const auto request_so = BinaryHttpRequest::Create(data);
  ASSERT_TRUE(request_so.ok());
  const BinaryHttpRequest request = *request_so;
  ASSERT_THAT(request.control_data(),
              FieldsAre("GET", "https", "www.example.com", "/hello.txt"));
  std::vector<BinaryHttpMessage::Field> expected_fields = {
      {"user-agent", "curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3"},
      {"accept-language", "en, mi"}};
  ASSERT_THAT(request.GetHeaderFields(), ContainerEq(expected_fields));
  ASSERT_EQ(request.body(), "");
  EXPECT_THAT(
      request.DebugString(),
      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=curl/"
            "7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l "
            "zlib/1.2.3};Field{accept-language=en, mi}}Body{}}}"));
}

TEST(BinaryHttpRequest, EncodePostBody) {
  /*
  POST /hello.txt HTTP/1.1
  User-Agent: not/telling
  Host: www.example.com
  Accept-Language: en

  Some body that I used to post.
  */
  BinaryHttpRequest request({"POST", "https", "www.example.com", "/hello.txt"});
  request.AddHeaderField({"User-Agent", "not/telling"})
      ->AddHeaderField({"Host", "www.example.com"})
      ->AddHeaderField({"Accept-Language", "en"})
      ->set_body({"Some body that I used to post.\r\n"});
  /*
    00000000: 0004504f 53540568 74747073 000a2f68  ..POST.https../h
    00000010: 656c6c6f 2e747874 3f0a7573 65722d61  ello.txt?.user-a
    00000020: 67656e74 0b6e6f74 2f74656c 6c696e67  gent.not/telling
    00000030: 04686f73 740f7777 772e6578 616d706c  .host.www.exampl
    00000040: 652e636f 6d0f6163 63657074 2d6c616e  e.com.accept-lan
    00000050: 67756167 6502656e 20536f6d 6520626f  guage.en Some bo
    00000060: 64792074 68617420 49207573 65642074  dy that I used t
    00000070: 6f20706f 73742e0d 0a                 o post....
  */
  const uint32_t expected_words[] = {
      0x0004504f, 0x53540568, 0x74747073, 0x000a2f68, 0x656c6c6f, 0x2e747874,
      0x3f0a7573, 0x65722d61, 0x67656e74, 0x0b6e6f74, 0x2f74656c, 0x6c696e67,
      0x04686f73, 0x740f7777, 0x772e6578, 0x616d706c, 0x652e636f, 0x6d0f6163,
      0x63657074, 0x2d6c616e, 0x67756167, 0x6502656e, 0x20536f6d, 0x6520626f,
      0x64792074, 0x68617420, 0x49207573, 0x65642074, 0x6f20706f, 0x73742e0d,
      0x0a000000};
  std::string expected;
  for (const auto& word : expected_words) {
    expected += WordToBytes(word);
  }
  // Remove padding.
  expected.resize(expected.size() - 3);
  const auto result = request.Serialize();
  ASSERT_TRUE(result.ok());
  ASSERT_EQ(*result, expected);
  EXPECT_THAT(
      request.DebugString(),
      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=not/"
            "telling};Field{host=www.example.com};Field{accept-language=en}}"
            "Body{Some "
            "body that I used to post.\r\n}}}"));
}

TEST(BinaryHttpRequest, DecodePostBody) {
  const uint32_t words[] = {
      0x0004504f, 0x53540568, 0x74747073, 0x000a2f68, 0x656c6c6f, 0x2e747874,
      0x3f0a7573, 0x65722d61, 0x67656e74, 0x0b6e6f74, 0x2f74656c, 0x6c696e67,
      0x04686f73, 0x740f7777, 0x772e6578, 0x616d706c, 0x652e636f, 0x6d0f6163,
      0x63657074, 0x2d6c616e, 0x67756167, 0x6502656e, 0x20536f6d, 0x6520626f,
      0x64792074, 0x68617420, 0x49207573, 0x65642074, 0x6f20706f, 0x73742e0d,
      0x0a000000};
  std::string data;
  for (const auto& word : words) {
    data += WordToBytes(word);
  }
  const auto request_so = BinaryHttpRequest::Create(data);
  ASSERT_TRUE(request_so.ok());
  BinaryHttpRequest request = *request_so;
  ASSERT_THAT(request.control_data(),
              FieldsAre("POST", "https", "", "/hello.txt"));
  std::vector<BinaryHttpMessage::Field> expected_fields = {
      {"user-agent", "not/telling"},
      {"host", "www.example.com"},
      {"accept-language", "en"}};
  ASSERT_THAT(request.GetHeaderFields(), ContainerEq(expected_fields));
  ASSERT_EQ(request.body(), "Some body that I used to post.\r\n");
  EXPECT_THAT(
      request.DebugString(),
      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=not/"
            "telling};Field{host=www.example.com};Field{accept-language=en}}"
            "Body{Some "
            "body that I used to post.\r\n}}}"));
}

TEST(BinaryHttpRequest, Equality) {
  BinaryHttpRequest request({"POST", "https", "www.example.com", "/hello.txt"});
  request.AddHeaderField({"User-Agent", "not/telling"})
      ->set_body({"hello, world!\r\n"});

  BinaryHttpRequest same({"POST", "https", "www.example.com", "/hello.txt"});
  same.AddHeaderField({"User-Agent", "not/telling"})
      ->set_body({"hello, world!\r\n"});
  EXPECT_EQ(request, same);
}

TEST(BinaryHttpRequest, Inequality) {
  BinaryHttpRequest request({"POST", "https", "www.example.com", "/hello.txt"});
  request.AddHeaderField({"User-Agent", "not/telling"})
      ->set_body({"hello, world!\r\n"});

  BinaryHttpRequest different_control(
      {"PUT", "https", "www.example.com", "/hello.txt"});
  different_control.AddHeaderField({"User-Agent", "not/telling"})
      ->set_body({"hello, world!\r\n"});
  EXPECT_NE(request, different_control);

  BinaryHttpRequest different_header(
      {"PUT", "https", "www.example.com", "/hello.txt"});
  different_header.AddHeaderField({"User-Agent", "told/you"})
      ->set_body({"hello, world!\r\n"});
  EXPECT_NE(request, different_header);

  BinaryHttpRequest no_header(
      {"PUT", "https", "www.example.com", "/hello.txt"});
  no_header.set_body({"hello, world!\r\n"});
  EXPECT_NE(request, no_header);

  BinaryHttpRequest different_body(
      {"POST", "https", "www.example.com", "/hello.txt"});
  different_body.AddHeaderField({"User-Agent", "not/telling"})
      ->set_body({"goodbye, world!\r\n"});
  EXPECT_NE(request, different_body);

  BinaryHttpRequest no_body({"POST", "https", "www.example.com", "/hello.txt"});
  no_body.AddHeaderField({"User-Agent", "not/telling"});
  EXPECT_NE(request, no_body);
}

TEST(BinaryHttpResponse, EncodeNoBody) {
  /*
    HTTP/1.1 404 Not Found
    Server: Apache
  */
  BinaryHttpResponse response(404);
  response.AddHeaderField({"Server", "Apache"});
  /*
    0141940e 06736572 76657206 41706163  .A...server.Apac
    686500                               he..
  */
  const uint32_t expected_words[] = {0x0141940e, 0x06736572, 0x76657206,
                                     0x41706163, 0x68650000};
  std::string expected;
  for (const auto& word : expected_words) {
    expected += WordToBytes(word);
  }
  // Remove padding.
  expected.resize(expected.size() - 1);
  const auto result = response.Serialize();
  ASSERT_TRUE(result.ok());
  ASSERT_EQ(*result, expected);
  EXPECT_THAT(
      response.DebugString(),
      StrEq("BinaryHttpResponse(404){BinaryHttpMessage{Headers{Field{server="
            "Apache}}Body{}}}"));
}

TEST(BinaryHttpResponse, DecodeNoBody) {
  /*
    HTTP/1.1 404 Not Found
    Server: Apache
  */
  const uint32_t words[] = {0x0141940e, 0x06736572, 0x76657206, 0x41706163,
                            0x68650000};
  std::string data;
  for (const auto& word : words) {
    data += WordToBytes(word);
  }
  const auto response_so = BinaryHttpResponse::Create(data);
  ASSERT_TRUE(response_so.ok());
  const BinaryHttpResponse response = *response_so;
  ASSERT_EQ(response.status_code(), 404);
  std::vector<BinaryHttpMessage::Field> expected_fields = {
      {"server", "Apache"}};
  ASSERT_THAT(response.GetHeaderFields(), ContainerEq(expected_fields));
  ASSERT_EQ(response.body(), "");
  ASSERT_TRUE(response.informational_responses().empty());
  EXPECT_THAT(
      response.DebugString(),
      StrEq("BinaryHttpResponse(404){BinaryHttpMessage{Headers{Field{server="
            "Apache}}Body{}}}"));
}

TEST(BinaryHttpResponse, EncodeBody) {
  /*
    HTTP/1.1 200 OK
    Server: Apache

    Hello, world!
  */
  BinaryHttpResponse response(200);
  response.AddHeaderField({"Server", "Apache"});
  response.set_body("Hello, world!\r\n");
  /*
    0140c80e 06736572 76657206 41706163  .@...server.Apac
    68650f48 656c6c6f 2c20776f 726c6421  he.Hello, world!
    0d0a                                 ....
  */
  const uint32_t expected_words[] = {0x0140c80e, 0x06736572, 0x76657206,
                                     0x41706163, 0x68650f48, 0x656c6c6f,
                                     0x2c20776f, 0x726c6421, 0x0d0a0000};
  std::string expected;
  for (const auto& word : expected_words) {
    expected += WordToBytes(word);
  }
  // Remove padding.
  expected.resize(expected.size() - 2);

  const auto result = response.Serialize();
  ASSERT_TRUE(result.ok());
  ASSERT_EQ(*result, expected);
  EXPECT_THAT(
      response.DebugString(),
      StrEq("BinaryHttpResponse(200){BinaryHttpMessage{Headers{Field{server="
            "Apache}}Body{Hello, world!\r\n}}}"));
}

TEST(BinaryHttpResponse, DecodeBody) {
  /*
    HTTP/1.1 200 OK

    Hello, world!
  */
  const uint32_t words[] = {0x0140c80e, 0x06736572, 0x76657206,
                            0x41706163, 0x68650f48, 0x656c6c6f,
                            0x2c20776f, 0x726c6421, 0x0d0a0000};
  std::string data;
  for (const auto& word : words) {
    data += WordToBytes(word);
  }
  const auto response_so = BinaryHttpResponse::Create(data);
  ASSERT_TRUE(response_so.ok());
  const BinaryHttpResponse response = *response_so;
  ASSERT_EQ(response.status_code(), 200);
  std::vector<BinaryHttpMessage::Field> expected_fields = {
      {"server", "Apache"}};
  ASSERT_THAT(response.GetHeaderFields(), ContainerEq(expected_fields));
  ASSERT_EQ(response.body(), "Hello, world!\r\n");
  ASSERT_TRUE(response.informational_responses().empty());
  EXPECT_THAT(
      response.DebugString(),
      StrEq("BinaryHttpResponse(200){BinaryHttpMessage{Headers{Field{server="
            "Apache}}Body{Hello, world!\r\n}}}"));
}

TEST(BHttpResponse, AddBadInformationalResponseCode) {
  BinaryHttpResponse response(200);
  ASSERT_FALSE(response.AddInformationalResponse(50, {}).ok());
  ASSERT_FALSE(response.AddInformationalResponse(300, {}).ok());
}

TEST(BinaryHttpResponse, EncodeMultiInformationalWithBody) {
  /*
    HTTP/1.1 102 Processing
    Running: "sleep 15"

    HTTP/1.1 103 Early Hints
    Link: </style.css>; rel=preload; as=style
    Link: </script.js>; rel=preload; as=script

    HTTP/1.1 200 OK
    Date: Mon, 27 Jul 2009 12:28:53 GMT
    Server: Apache
    Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
    ETag: "34aa387-d-1568eb00"
    Accept-Ranges: bytes
    Content-Length: 51
    Vary: Accept-Encoding
    Content-Type: text/plain

    Hello World! My content includes a trailing CRLF.
  */
  BinaryHttpResponse response(200);
  response.AddHeaderField({"Date", "Mon, 27 Jul 2009 12:28:53 GMT"})
      ->AddHeaderField({"Server", "Apache"})
      ->AddHeaderField({"Last-Modified", "Wed, 22 Jul 2009 19:15:56 GMT"})
      ->AddHeaderField({"ETag", "\"34aa387-d-1568eb00\""})
      ->AddHeaderField({"Accept-Ranges", "bytes"})
      ->AddHeaderField({"Content-Length", "51"})
      ->AddHeaderField({"Vary", "Accept-Encoding"})
      ->AddHeaderField({"Content-Type", "text/plain"});
  response.set_body("Hello World! My content includes a trailing CRLF.\r\n");
  ASSERT_TRUE(
      response.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}})
          .ok());
  ASSERT_TRUE(response
                  .AddInformationalResponse(
                      103, {{"Link", "</style.css>; rel=preload; as=style"},
                            {"Link", "</script.js>; rel=preload; as=script"}})
                  .ok());

  /*
      01406613 0772756e 6e696e67 0a22736c  .@f..running."sl
      65657020 31352240 67405304 6c696e6b  eep 15"@g@S.link
      233c2f73 74796c65 2e637373 3e3b2072  #</style.css>; r
      656c3d70 72656c6f 61643b20 61733d73  el=preload; as=s
      74796c65 046c696e 6b243c2f 73637269  tyle.link$</scri
      70742e6a 733e3b20 72656c3d 7072656c  pt.js>; rel=prel
      6f61643b 2061733d 73637269 707440c8  oad; as=script@.
      40ca0464 6174651d 4d6f6e2c 20323720  @..date.Mon, 27
      4a756c20 32303039 2031323a 32383a35  Jul 2009 12:28:5
      3320474d 54067365 72766572 06417061  3 GMT.server.Apa
      6368650d 6c617374 2d6d6f64 69666965  che.last-modifie
      641d5765 642c2032 32204a75 6c203230  d.Wed, 22 Jul 20
      30392031 393a3135 3a353620 474d5404  09 19:15:56 GMT.
      65746167 14223334 61613338 372d642d  etag."34aa387-d-
      31353638 65623030 220d6163 63657074  1568eb00".accept
      2d72616e 67657305 62797465 730e636f  -ranges.bytes.co
      6e74656e 742d6c65 6e677468 02353104  ntent-length.51.
      76617279 0f416363 6570742d 456e636f  vary.Accept-Enco
      64696e67 0c636f6e 74656e74 2d747970  ding.content-typ
      650a7465 78742f70 6c61696e 3348656c  e.text/plain3Hel
      6c6f2057 6f726c64 21204d79 20636f6e  lo World! My con
      74656e74 20696e63 6c756465 73206120  tent includes a
      74726169 6c696e67 2043524c 462e0d0a  trailing CRLF...
  */
  const uint32_t expected_words[] = {
      0x01406613, 0x0772756e, 0x6e696e67, 0x0a22736c, 0x65657020, 0x31352240,
      0x67405304, 0x6c696e6b, 0x233c2f73, 0x74796c65, 0x2e637373, 0x3e3b2072,
      0x656c3d70, 0x72656c6f, 0x61643b20, 0x61733d73, 0x74796c65, 0x046c696e,
      0x6b243c2f, 0x73637269, 0x70742e6a, 0x733e3b20, 0x72656c3d, 0x7072656c,
      0x6f61643b, 0x2061733d, 0x73637269, 0x707440c8, 0x40ca0464, 0x6174651d,
      0x4d6f6e2c, 0x20323720, 0x4a756c20, 0x32303039, 0x2031323a, 0x32383a35,
      0x3320474d, 0x54067365, 0x72766572, 0x06417061, 0x6368650d, 0x6c617374,
      0x2d6d6f64, 0x69666965, 0x641d5765, 0x642c2032, 0x32204a75, 0x6c203230,
      0x30392031, 0x393a3135, 0x3a353620, 0x474d5404, 0x65746167, 0x14223334,
      0x61613338, 0x372d642d, 0x31353638, 0x65623030, 0x220d6163, 0x63657074,
      0x2d72616e, 0x67657305, 0x62797465, 0x730e636f, 0x6e74656e, 0x742d6c65,
      0x6e677468, 0x02353104, 0x76617279, 0x0f416363, 0x6570742d, 0x456e636f,
      0x64696e67, 0x0c636f6e, 0x74656e74, 0x2d747970, 0x650a7465, 0x78742f70,
      0x6c61696e, 0x3348656c, 0x6c6f2057, 0x6f726c64, 0x21204d79, 0x20636f6e,
      0x74656e74, 0x20696e63, 0x6c756465, 0x73206120, 0x74726169, 0x6c696e67,
      0x2043524c, 0x462e0d0a};
  std::string expected;
  for (const auto& word : expected_words) {
    expected += WordToBytes(word);
  }
  const auto result = response.Serialize();
  ASSERT_TRUE(result.ok());
  ASSERT_EQ(*result, expected);
  EXPECT_THAT(
      response.DebugString(),
      StrEq(
          "BinaryHttpResponse(200){BinaryHttpMessage{Headers{Field{date=Mon, "
          "27 Jul 2009 12:28:53 "
          "GMT};Field{server=Apache};Field{last-modified=Wed, 22 Jul 2009 "
          "19:15:56 "
          "GMT};Field{etag=\"34aa387-d-1568eb00\"};Field{accept-ranges=bytes};"
          "Field{"
          "content-length=51};Field{vary=Accept-Encoding};Field{content-type="
          "text/plain}}Body{Hello World! My content includes a trailing "
          "CRLF.\r\n}}InformationalResponse{Field{running=\"sleep "
          "15\"}};InformationalResponse{Field{link=</style.css>; rel=preload; "
          "as=style};Field{link=</script.js>; rel=preload; as=script}}}"));
  TestPrintTo(response);
}

TEST(BinaryHttpResponse, DecodeMultiInformationalWithBody) {
  /*
    HTTP/1.1 102 Processing
    Running: "sleep 15"

    HTTP/1.1 103 Early Hints
    Link: </style.css>; rel=preload; as=style
    Link: </script.js>; rel=preload; as=script

    HTTP/1.1 200 OK
    Date: Mon, 27 Jul 2009 12:28:53 GMT
    Server: Apache
    Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
    ETag: "34aa387-d-1568eb00"
    Accept-Ranges: bytes
    Content-Length: 51
    Vary: Accept-Encoding
    Content-Type: text/plain

    Hello World! My content includes a trailing CRLF.
  */
  const uint32_t words[] = {
      0x01406613, 0x0772756e, 0x6e696e67, 0x0a22736c, 0x65657020, 0x31352240,
      0x67405304, 0x6c696e6b, 0x233c2f73, 0x74796c65, 0x2e637373, 0x3e3b2072,
      0x656c3d70, 0x72656c6f, 0x61643b20, 0x61733d73, 0x74796c65, 0x046c696e,
      0x6b243c2f, 0x73637269, 0x70742e6a, 0x733e3b20, 0x72656c3d, 0x7072656c,
      0x6f61643b, 0x2061733d, 0x73637269, 0x707440c8, 0x40ca0464, 0x6174651d,
      0x4d6f6e2c, 0x20323720, 0x4a756c20, 0x32303039, 0x2031323a, 0x32383a35,
      0x3320474d, 0x54067365, 0x72766572, 0x06417061, 0x6368650d, 0x6c617374,
      0x2d6d6f64, 0x69666965, 0x641d5765, 0x642c2032, 0x32204a75, 0x6c203230,
      0x30392031, 0x393a3135, 0x3a353620, 0x474d5404, 0x65746167, 0x14223334,
      0x61613338, 0x372d642d, 0x31353638, 0x65623030, 0x220d6163, 0x63657074,
      0x2d72616e, 0x67657305, 0x62797465, 0x730e636f, 0x6e74656e, 0x742d6c65,
      0x6e677468, 0x02353104, 0x76617279, 0x0f416363, 0x6570742d, 0x456e636f,
      0x64696e67, 0x0c636f6e, 0x74656e74, 0x2d747970, 0x650a7465, 0x78742f70,
      0x6c61696e, 0x3348656c, 0x6c6f2057, 0x6f726c64, 0x21204d79, 0x20636f6e,
      0x74656e74, 0x20696e63, 0x6c756465, 0x73206120, 0x74726169, 0x6c696e67,
      0x2043524c, 0x462e0d0a, 0x00000000};
  std::string data;
  for (const auto& word : words) {
    data += WordToBytes(word);
  }
  const auto response_so = BinaryHttpResponse::Create(data);
  ASSERT_TRUE(response_so.ok());
  const BinaryHttpResponse response = *response_so;
  std::vector<BinaryHttpMessage::Field> expected_fields = {
      {"date", "Mon, 27 Jul 2009 12:28:53 GMT"},
      {"server", "Apache"},
      {"last-modified", "Wed, 22 Jul 2009 19:15:56 GMT"},
      {"etag", "\"34aa387-d-1568eb00\""},
      {"accept-ranges", "bytes"},
      {"content-length", "51"},
      {"vary", "Accept-Encoding"},
      {"content-type", "text/plain"}};

  ASSERT_THAT(response.GetHeaderFields(), ContainerEq(expected_fields));
  ASSERT_EQ(response.body(),
            "Hello World! My content includes a trailing CRLF.\r\n");
  std::vector<BinaryHttpMessage::Field> header102 = {
      {"running", "\"sleep 15\""}};
  std::vector<BinaryHttpMessage::Field> header103 = {
      {"link", "</style.css>; rel=preload; as=style"},
      {"link", "</script.js>; rel=preload; as=script"}};
  std::vector<BinaryHttpResponse::InformationalResponse> expected_control = {
      {102, header102}, {103, header103}};
  ASSERT_THAT(response.informational_responses(),
              ContainerEq(expected_control));
  EXPECT_THAT(
      response.DebugString(),
      StrEq(
          "BinaryHttpResponse(200){BinaryHttpMessage{Headers{Field{date=Mon, "
          "27 Jul 2009 12:28:53 "
          "GMT};Field{server=Apache};Field{last-modified=Wed, 22 Jul 2009 "
          "19:15:56 "
          "GMT};Field{etag=\"34aa387-d-1568eb00\"};Field{accept-ranges=bytes};"
          "Field{"
          "content-length=51};Field{vary=Accept-Encoding};Field{content-type="
          "text/plain}}Body{Hello World! My content includes a trailing "
          "CRLF.\r\n}}InformationalResponse{Field{running=\"sleep "
          "15\"}};InformationalResponse{Field{link=</style.css>; rel=preload; "
          "as=style};Field{link=</script.js>; rel=preload; as=script}}}"));
  TestPrintTo(response);
}

TEST(BinaryHttpMessage, SwapBody) {
  BinaryHttpRequest request({});
  request.set_body("hello, world!");
  std::string other = "goodbye, world!";
  request.swap_body(other);
  EXPECT_EQ(request.body(), "goodbye, world!");
  EXPECT_EQ(other, "hello, world!");
}

TEST(BinaryHttpResponse, Equality) {
  BinaryHttpResponse response(200);
  response.AddHeaderField({"Server", "Apache"})->set_body("Hello, world!\r\n");
  ASSERT_TRUE(
      response.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}})
          .ok());

  BinaryHttpResponse same(200);
  same.AddHeaderField({"Server", "Apache"})->set_body("Hello, world!\r\n");
  ASSERT_TRUE(
      same.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}}).ok());
  ASSERT_EQ(response, same);
}

TEST(BinaryHttpResponse, Inequality) {
  BinaryHttpResponse response(200);
  response.AddHeaderField({"Server", "Apache"})->set_body("Hello, world!\r\n");
  ASSERT_TRUE(
      response.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}})
          .ok());

  BinaryHttpResponse different_status(201);
  different_status.AddHeaderField({"Server", "Apache"})
      ->set_body("Hello, world!\r\n");
  EXPECT_TRUE(different_status
                  .AddInformationalResponse(102, {{"Running", "\"sleep 15\""}})
                  .ok());
  EXPECT_NE(response, different_status);

  BinaryHttpResponse different_header(200);
  different_header.AddHeaderField({"Server", "python3"})
      ->set_body("Hello, world!\r\n");
  EXPECT_TRUE(different_header
                  .AddInformationalResponse(102, {{"Running", "\"sleep 15\""}})
                  .ok());
  EXPECT_NE(response, different_header);

  BinaryHttpResponse no_header(200);
  no_header.set_body("Hello, world!\r\n");
  EXPECT_TRUE(
      no_header.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}})
          .ok());
  EXPECT_NE(response, no_header);

  BinaryHttpResponse different_body(200);
  different_body.AddHeaderField({"Server", "Apache"})
      ->set_body("Goodbye, world!\r\n");
  EXPECT_TRUE(different_body
                  .AddInformationalResponse(102, {{"Running", "\"sleep 15\""}})
                  .ok());
  EXPECT_NE(response, different_body);

  BinaryHttpResponse no_body(200);
  no_body.AddHeaderField({"Server", "Apache"});
  EXPECT_TRUE(
      no_body.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}})
          .ok());
  EXPECT_NE(response, no_body);

  BinaryHttpResponse different_informational(200);
  different_informational.AddHeaderField({"Server", "Apache"})
      ->set_body("Hello, world!\r\n");
  EXPECT_TRUE(different_informational
                  .AddInformationalResponse(198, {{"Running", "\"sleep 15\""}})
                  .ok());
  EXPECT_NE(response, different_informational);

  BinaryHttpResponse no_informational(200);
  no_informational.AddHeaderField({"Server", "Apache"})
      ->set_body("Hello, world!\r\n");
  EXPECT_NE(response, no_informational);
}

MATCHER_P(HasEqPayload, value, "Payloads of messages are equivalent.") {
  return arg.IsPayloadEqual(value);
}

template <typename T>
void TestPadding(T& message) {
  const auto data_so = message.Serialize();
  ASSERT_TRUE(data_so.ok());
  auto data = *data_so;
  ASSERT_EQ(data.size(), message.EncodedSize());

  message.set_num_padding_bytes(10);
  const auto padded_data_so = message.Serialize();
  ASSERT_TRUE(padded_data_so.ok());
  const auto padded_data = *padded_data_so;
  ASSERT_EQ(padded_data.size(), message.EncodedSize());

  // Check padding size output.
  ASSERT_EQ(data.size() + 10, padded_data.size());
  // Check for valid null byte padding output
  data.resize(data.size() + 10);
  ASSERT_EQ(data, padded_data);

  // Deserialize padded and not padded, and verify they are the same.
  const auto deserialized_padded_message_so = T::Create(data);
  ASSERT_TRUE(deserialized_padded_message_so.ok());
  const auto deserialized_padded_message = *deserialized_padded_message_so;
  ASSERT_EQ(deserialized_padded_message, message);
  ASSERT_EQ(deserialized_padded_message.num_padding_bytes(), size_t(10));

  // Invalid padding
  data[data.size() - 1] = 'a';
  const auto bad_so = T::Create(data);
  ASSERT_FALSE(bad_so.ok());

  // Check that padding does not impact equality.
  data.resize(data.size() - 10);
  const auto deserialized_message_so = T::Create(data);
  ASSERT_TRUE(deserialized_message_so.ok());
  const auto deserialized_message = *deserialized_message_so;
  ASSERT_EQ(deserialized_message.num_padding_bytes(), size_t(0));
  // Confirm that the message payloads are equal, but not fully equivalent due
  // to padding.
  ASSERT_THAT(deserialized_message, HasEqPayload(deserialized_padded_message));
  ASSERT_NE(deserialized_message, deserialized_padded_message);
}

TEST(BinaryHttpRequest, Padding) {
  /*
    GET /hello.txt HTTP/1.1
    User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
    Host: www.example.com
    Accept-Language: en, mi
  */
  BinaryHttpRequest request({"GET", "https", "", "/hello.txt"});
  request
      .AddHeaderField({"User-Agent",
                       "curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3"})
      ->AddHeaderField({"Host", "www.example.com"})
      ->AddHeaderField({"Accept-Language", "en, mi"});
  TestPadding(request);
}

TEST(BinaryHttpResponse, Padding) {
  /*
    HTTP/1.1 200 OK
    Server: Apache

    Hello, world!
  */
  BinaryHttpResponse response(200);
  response.AddHeaderField({"Server", "Apache"});
  response.set_body("Hello, world!\r\n");
  TestPadding(response);
}

}  // namespace quiche
