// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/spdy/hpack_encoder.h"

#include <map>
#include <string>

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

using base::StringPiece;
using std::string;
using testing::ElementsAre;

namespace test {

class HpackHeaderTablePeer {
 public:
  explicit HpackHeaderTablePeer(HpackHeaderTable* table)
      : table_(table) {}

  HpackHeaderTable::EntryTable* dynamic_entries() {
    return &table_->dynamic_entries_;
  }

 private:
  HpackHeaderTable* table_;
};

class HpackEncoderPeer {
 public:
  typedef HpackEncoder::Representation Representation;
  typedef HpackEncoder::Representations Representations;

  explicit HpackEncoderPeer(HpackEncoder* encoder)
    : encoder_(encoder) {}

  HpackHeaderTable* table() {
    return &encoder_->header_table_;
  }
  HpackHeaderTablePeer table_peer() {
    return HpackHeaderTablePeer(table());
  }
  void set_allow_huffman_compression(bool allow) {
    encoder_->allow_huffman_compression_ = allow;
  }
  void EmitString(StringPiece str) {
    encoder_->EmitString(str);
  }
  void TakeString(string* out) {
    encoder_->output_stream_.TakeString(out);
  }
  void UpdateCharacterCounts(StringPiece str) {
    encoder_->UpdateCharacterCounts(str);
  }
  static void CookieToCrumbs(StringPiece cookie,
                             std::vector<StringPiece>* out) {
    Representations tmp;
    HpackEncoder::CookieToCrumbs(std::make_pair("", cookie), &tmp);

    out->clear();
    for (size_t i = 0; i != tmp.size(); ++i) {
      out->push_back(tmp[i].second);
    }
  }
  static void DecomposeRepresentation(StringPiece value,
                                      std::vector<StringPiece>* out) {
    Representations tmp;
    HpackEncoder::DecomposeRepresentation(std::make_pair("foobar", value),
                                          &tmp);

    out->clear();
    for (size_t i = 0; i != tmp.size(); ++i) {
      out->push_back(tmp[i].second);
    }
  }

 private:
  HpackEncoder* encoder_;
};

}  // namespace test

namespace {

using std::map;
using testing::ElementsAre;

class HpackEncoderTest : public ::testing::Test {
 protected:
  typedef test::HpackEncoderPeer::Representations Representations;

  HpackEncoderTest()
      : encoder_(ObtainHpackHuffmanTable()),
        peer_(&encoder_),
        static_(peer_.table()->GetByIndex(1)) {}

  void SetUp() override {
    // Populate dynamic entries into the table fixture. For simplicity each
    // entry has name.size() + value.size() == 10.
    key_1_ = peer_.table()->TryAddEntry("key1", "value1");
    key_2_ = peer_.table()->TryAddEntry("key2", "value2");
    cookie_a_ = peer_.table()->TryAddEntry("cookie", "a=bb");
    cookie_c_ = peer_.table()->TryAddEntry("cookie", "c=dd");

    // No further insertions may occur without evictions.
    peer_.table()->SetMaxSize(peer_.table()->size());

    // Disable Huffman coding by default. Most tests don't care about it.
    peer_.set_allow_huffman_compression(false);
  }

  void ExpectIndex(size_t index) {
    expected_.AppendPrefix(kIndexedOpcode);
    expected_.AppendUint32(index);
  }
  void ExpectIndexedLiteral(const HpackEntry* key_entry, StringPiece value) {
    expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
    expected_.AppendUint32(IndexOf(key_entry));
    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
    expected_.AppendUint32(value.size());
    expected_.AppendBytes(value);
  }
  void ExpectIndexedLiteral(StringPiece name, StringPiece value) {
    expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
    expected_.AppendUint32(0);
    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
    expected_.AppendUint32(name.size());
    expected_.AppendBytes(name);
    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
    expected_.AppendUint32(value.size());
    expected_.AppendBytes(value);
  }
  void ExpectNonIndexedLiteral(StringPiece name, StringPiece value) {
    expected_.AppendPrefix(kLiteralNoIndexOpcode);
    expected_.AppendUint32(0);
    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
    expected_.AppendUint32(name.size());
    expected_.AppendBytes(name);
    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
    expected_.AppendUint32(value.size());
    expected_.AppendBytes(value);
  }
  void CompareWithExpectedEncoding(const map<string, string>& header_set) {
    string expected_out, actual_out;
    expected_.TakeString(&expected_out);
    EXPECT_TRUE(encoder_.EncodeHeaderSet(header_set, &actual_out));
    EXPECT_EQ(expected_out, actual_out);
  }
  size_t IndexOf(const HpackEntry* entry) {
    return peer_.table()->IndexOf(entry);
  }

  HpackEncoder encoder_;
  test::HpackEncoderPeer peer_;

  const HpackEntry* static_;
  const HpackEntry* key_1_;
  const HpackEntry* key_2_;
  const HpackEntry* cookie_a_;
  const HpackEntry* cookie_c_;

  HpackOutputStream expected_;
};

TEST_F(HpackEncoderTest, SingleDynamicIndex) {
  ExpectIndex(IndexOf(key_2_));

  map<string, string> headers;
  headers[key_2_->name()] = key_2_->value();
  CompareWithExpectedEncoding(headers);
}

TEST_F(HpackEncoderTest, SingleStaticIndex) {
  ExpectIndex(IndexOf(static_));

  map<string, string> headers;
  headers[static_->name()] = static_->value();
  CompareWithExpectedEncoding(headers);
}

TEST_F(HpackEncoderTest, SingleStaticIndexTooLarge) {
  peer_.table()->SetMaxSize(1);  // Also evicts all fixtures.
  ExpectIndex(IndexOf(static_));

  map<string, string> headers;
  headers[static_->name()] = static_->value();
  CompareWithExpectedEncoding(headers);

  EXPECT_EQ(0u, peer_.table_peer().dynamic_entries()->size());
}

TEST_F(HpackEncoderTest, SingleLiteralWithIndexName) {
  ExpectIndexedLiteral(key_2_, "value3");

  map<string, string> headers;
  headers[key_2_->name()] = "value3";
  CompareWithExpectedEncoding(headers);

  // A new entry was inserted and added to the reference set.
  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
  EXPECT_EQ(new_entry->name(), key_2_->name());
  EXPECT_EQ(new_entry->value(), "value3");
}

TEST_F(HpackEncoderTest, SingleLiteralWithLiteralName) {
  ExpectIndexedLiteral("key3", "value3");

  map<string, string> headers;
  headers["key3"] = "value3";
  CompareWithExpectedEncoding(headers);

  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
  EXPECT_EQ(new_entry->name(), "key3");
  EXPECT_EQ(new_entry->value(), "value3");
}

TEST_F(HpackEncoderTest, SingleLiteralTooLarge) {
  peer_.table()->SetMaxSize(1);  // Also evicts all fixtures.

  ExpectIndexedLiteral("key3", "value3");

  // A header overflowing the header table is still emitted.
  // The header table is empty.
  map<string, string> headers;
  headers["key3"] = "value3";
  CompareWithExpectedEncoding(headers);

  EXPECT_EQ(0u, peer_.table_peer().dynamic_entries()->size());
}

TEST_F(HpackEncoderTest, EmitThanEvict) {
  // |key_1_| is toggled and placed into the reference set,
  // and then immediately evicted by "key3".
  ExpectIndex(IndexOf(key_1_));
  ExpectIndexedLiteral("key3", "value3");

  map<string, string> headers;
  headers[key_1_->name()] = key_1_->value();
  headers["key3"] = "value3";
  CompareWithExpectedEncoding(headers);
}

TEST_F(HpackEncoderTest, CookieHeaderIsCrumbled) {
  ExpectIndex(IndexOf(cookie_a_));
  ExpectIndex(IndexOf(cookie_c_));
  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "e=ff");

  map<string, string> headers;
  headers["cookie"] = "e=ff; a=bb; c=dd";
  CompareWithExpectedEncoding(headers);
}

TEST_F(HpackEncoderTest, StringsDynamicallySelectHuffmanCoding) {
  peer_.set_allow_huffman_compression(true);

  // Compactable string. Uses Huffman coding.
  peer_.EmitString("feedbeef");
  expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
  expected_.AppendUint32(6);
  expected_.AppendBytes("\x94\xA5\x92""2\x96_");

  // Non-compactable. Uses identity coding.
  peer_.EmitString("@@@@@@");
  expected_.AppendPrefix(kStringLiteralIdentityEncoded);
  expected_.AppendUint32(6);
  expected_.AppendBytes("@@@@@@");

  string expected_out, actual_out;
  expected_.TakeString(&expected_out);
  peer_.TakeString(&actual_out);
  EXPECT_EQ(expected_out, actual_out);
}

TEST_F(HpackEncoderTest, EncodingWithoutCompression) {
  // Implementation should internally disable.
  peer_.set_allow_huffman_compression(true);

  ExpectNonIndexedLiteral(":path", "/index.html");
  ExpectNonIndexedLiteral("cookie", "foo=bar; baz=bing");
  ExpectNonIndexedLiteral("hello", "goodbye");

  map<string, string> headers;
  headers[":path"] = "/index.html";
  headers["cookie"] = "foo=bar; baz=bing";
  headers["hello"] = "goodbye";

  string expected_out, actual_out;
  expected_.TakeString(&expected_out);
  encoder_.EncodeHeaderSetWithoutCompression(headers, &actual_out);
  EXPECT_EQ(expected_out, actual_out);
}

TEST_F(HpackEncoderTest, MultipleEncodingPasses) {
  // Pass 1.
  {
    map<string, string> headers;
    headers["key1"] = "value1";
    headers["cookie"] = "a=bb";

    ExpectIndex(IndexOf(cookie_a_));
    ExpectIndex(IndexOf(key_1_));
    CompareWithExpectedEncoding(headers);
  }
  // Header table is:
  // 65: key1: value1
  // 64: key2: value2
  // 63: cookie: a=bb
  // 62: cookie: c=dd
  // Pass 2.
  {
    map<string, string> headers;
    headers["key2"] = "value2";
    headers["cookie"] = "c=dd; e=ff";

    ExpectIndex(IndexOf(cookie_c_));
    // This cookie evicts |key1| from the dynamic table.
    ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "e=ff");
    // "key2: value2"
    ExpectIndex(65);

    CompareWithExpectedEncoding(headers);
  }
  // Header table is:
  // 65: key2: value2
  // 64: cookie: a=bb
  // 63: cookie: c=dd
  // 62: cookie: e=ff
  // Pass 3.
  {
    map<string, string> headers;
    headers["key2"] = "value2";
    headers["cookie"] = "a=bb; b=cc; c=dd";

    // "cookie: a=bb"
    ExpectIndex(64);
    // This cookie evicts |key2| from the dynamic table.
    ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "b=cc");
    // "cookie: c=dd"
    ExpectIndex(64);
    // "key2: value2"
    ExpectIndexedLiteral("key2", "value2");

    CompareWithExpectedEncoding(headers);
  }
}

TEST_F(HpackEncoderTest, PseudoHeadersFirst) {
  map<string, string> headers;
  // A pseudo-header to be indexed.
  headers[":authority"] = "www.example.com";
  // A pseudo-header that should not be indexed.
  headers[":path"] = "/spam/eggs.html";
  // A regular header which precedes ":" alphabetically, should still be encoded
  // after pseudo-headers.
  headers["-foo"] = "bar";
  headers["foo"] = "bar";
  headers["cookie"] = "c=dd";

  // Pseudo-headers are encoded in alphabetical order.
  // This entry pushes "cookie: a=bb" back to 63.
  ExpectIndexedLiteral(peer_.table()->GetByName(":authority"),
                       "www.example.com");
  ExpectNonIndexedLiteral(":path", "/spam/eggs.html");
  // Regular headers are endoded in alphabetical order.
  // This entry pushes "cookie: a=bb" back to 64.
  ExpectIndexedLiteral("-foo", "bar");
  ExpectIndex(64);
  ExpectIndexedLiteral("foo", "bar");
  CompareWithExpectedEncoding(headers);
}

TEST_F(HpackEncoderTest, CookieToCrumbs) {
  test::HpackEncoderPeer peer(NULL);
  std::vector<StringPiece> out;

  // A space after ';' is consumed. All other spaces remain. ';' at beginning
  // and end of string produce empty crumbs. Duplicate crumbs are removed.
  // See section 8.1.3.4 "Compressing the Cookie Header Field" in the HTTP/2
  // specification at http://tools.ietf.org/html/draft-ietf-httpbis-http2-11
  peer.CookieToCrumbs(" foo=1;bar=2 ; bar=3;  bing=4; ", &out);
  EXPECT_THAT(out, ElementsAre("", " bing=4", " foo=1", "bar=2 ", "bar=3"));

  peer.CookieToCrumbs(";;foo = bar ;; ;baz =bing", &out);
  EXPECT_THAT(out, ElementsAre("", "baz =bing", "foo = bar "));

  peer.CookieToCrumbs("baz=bing; foo=bar; baz=bing", &out);
  EXPECT_THAT(out, ElementsAre("baz=bing", "foo=bar"));

  peer.CookieToCrumbs("baz=bing", &out);
  EXPECT_THAT(out, ElementsAre("baz=bing"));

  peer.CookieToCrumbs("", &out);
  EXPECT_THAT(out, ElementsAre(""));

  peer.CookieToCrumbs("foo;bar; baz;baz;bing;", &out);
  EXPECT_THAT(out, ElementsAre("", "bar", "baz", "bing", "foo"));
}

TEST_F(HpackEncoderTest, UpdateCharacterCounts) {
  std::vector<size_t> counts(256, 0);
  size_t total_counts = 0;
  encoder_.SetCharCountsStorage(&counts, &total_counts);

  char kTestString[] = "foo\0\1\xff""boo";
  peer_.UpdateCharacterCounts(
      StringPiece(kTestString, arraysize(kTestString) - 1));

  std::vector<size_t> expect(256, 0);
  expect[static_cast<uint8>('f')] = 1;
  expect[static_cast<uint8>('o')] = 4;
  expect[static_cast<uint8>('\0')] = 1;
  expect[static_cast<uint8>('\1')] = 1;
  expect[static_cast<uint8>('\xff')] = 1;
  expect[static_cast<uint8>('b')] = 1;

  EXPECT_EQ(expect, counts);
  EXPECT_EQ(9u, total_counts);
}

TEST_F(HpackEncoderTest, DecomposeRepresentation) {
  test::HpackEncoderPeer peer(NULL);
  std::vector<StringPiece> out;

  peer.DecomposeRepresentation("", &out);
  EXPECT_THAT(out, ElementsAre(""));

  peer.DecomposeRepresentation("foobar", &out);
  EXPECT_THAT(out, ElementsAre("foobar"));

  peer.DecomposeRepresentation(StringPiece("foo\0bar", 7), &out);
  EXPECT_THAT(out, ElementsAre("foo", "bar"));

  peer.DecomposeRepresentation(StringPiece("\0foo\0bar", 8), &out);
  EXPECT_THAT(out, ElementsAre("", "foo", "bar"));

  peer.DecomposeRepresentation(StringPiece("foo\0bar\0", 8), &out);
  EXPECT_THAT(out, ElementsAre("foo", "bar", ""));

  peer.DecomposeRepresentation(StringPiece("\0foo\0bar\0", 9), &out);
  EXPECT_THAT(out, ElementsAre("", "foo", "bar", ""));
}

// Test that encoded headers do not have \0-delimited multiple values, as this
// became disallowed in HTTP/2 draft-14.
TEST_F(HpackEncoderTest, CrumbleNullByteDelimitedValue) {
  map<string, string> headers;
  // A header field to be crumbled: "spam: foo\0bar".
  headers["spam"] = string("foo\0bar", 7);

  ExpectIndexedLiteral("spam", "foo");
  expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
  expected_.AppendUint32(62);
  expected_.AppendPrefix(kStringLiteralIdentityEncoded);
  expected_.AppendUint32(3);
  expected_.AppendBytes("bar");
  CompareWithExpectedEncoding(headers);
}

}  // namespace

}  // namespace net
