// Copyright (c) 2011 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/base/filter.h"
#include "net/base/mock_filter_context.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(COBALT)
#define MAYBE_SdchEncoding DISABLED_SdchEncoding
#define MAYBE_MissingSdchEncoding DISABLED_MissingSdchEncoding
#else
#define MAYBE_SdchEncoding SdchEncoding
#define MAYBE_MissingSdchEncoding MissingSdchEncoding
#endif

namespace net {

class FilterTest : public testing::Test {
};

TEST(FilterTest, ContentTypeId) {
  // Check for basic translation of Content-Encoding, including case variations.
  EXPECT_EQ(Filter::FILTER_TYPE_DEFLATE,
            Filter::ConvertEncodingToType("deflate"));
  EXPECT_EQ(Filter::FILTER_TYPE_DEFLATE,
            Filter::ConvertEncodingToType("deflAte"));
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
            Filter::ConvertEncodingToType("gzip"));
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
            Filter::ConvertEncodingToType("GzIp"));
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
            Filter::ConvertEncodingToType("x-gzip"));
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
            Filter::ConvertEncodingToType("X-GzIp"));
  EXPECT_EQ(Filter::FILTER_TYPE_SDCH,
            Filter::ConvertEncodingToType("sdch"));
  EXPECT_EQ(Filter::FILTER_TYPE_SDCH,
            Filter::ConvertEncodingToType("sDcH"));
  EXPECT_EQ(Filter::FILTER_TYPE_UNSUPPORTED,
            Filter::ConvertEncodingToType("weird"));
  EXPECT_EQ(Filter::FILTER_TYPE_UNSUPPORTED,
            Filter::ConvertEncodingToType("strange"));
}

// Check various fixups that modify content encoding lists.
TEST(FilterTest, ApacheGzip) {
  MockFilterContext filter_context;
  filter_context.SetSdchResponse(false);

  // Check that redundant gzip mime type removes only solo gzip encoding.
  const std::string kGzipMime1("application/x-gzip");
  const std::string kGzipMime2("application/gzip");
  const std::string kGzipMime3("application/x-gunzip");
  std::vector<Filter::FilterType> encoding_types;

  // First show it removes the gzip, given any gzip style mime type.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetMimeType(kGzipMime1);
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  EXPECT_TRUE(encoding_types.empty());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetMimeType(kGzipMime2);
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  EXPECT_TRUE(encoding_types.empty());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetMimeType(kGzipMime3);
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  EXPECT_TRUE(encoding_types.empty());

  // Check to be sure it doesn't remove everything when it has such a type.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
  filter_context.SetMimeType(kGzipMime1);
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types.front());

  // Check to be sure that gzip can survive with other mime types.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetMimeType("other/mime");
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
}

#if !defined(__LB_SHELL__)  // SDCH not supported in LB_SHELL
TEST(FilterTest, MAYBE_SdchEncoding) {
  // Handle content encodings including SDCH.
  const std::string kTextHtmlMime("text/html");
  MockFilterContext filter_context;
  filter_context.SetSdchResponse(true);

  std::vector<Filter::FilterType> encoding_types;

  // Check for most common encoding, and verify it survives unchanged.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetMimeType(kTextHtmlMime);
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(2U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);

  // Unchanged even with other mime types.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetMimeType("other/type");
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(2U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);

  // Solo SDCH is extended to include optional gunzip.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(2U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
}
#endif

#if !defined(__LB_SHELL__)  // SDCH not supported
TEST(FilterTest, MAYBE_MissingSdchEncoding) {
  // Handle interesting case where entire SDCH encoding assertion "got lost."
  const std::string kTextHtmlMime("text/html");
  MockFilterContext filter_context;
  filter_context.SetSdchResponse(true);

  std::vector<Filter::FilterType> encoding_types;

  // Loss of encoding, but it was an SDCH response with html type.
  encoding_types.clear();
  filter_context.SetMimeType(kTextHtmlMime);
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(2U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);

  // Loss of encoding, but it was an SDCH response with a prefix that says it
  // was an html type.  Note that it *should* be the case that a precise match
  // with "text/html" we be collected by GetMimeType() and passed in, but we
  // coded the fixup defensively (scanning for a prefix of "text/html", so this
  // is an example which could survive such confusion in the caller).
  encoding_types.clear();
  filter_context.SetMimeType("text/html; charset=UTF-8");
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(2U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);

  // No encoding, but it was an SDCH response with non-html type.
  encoding_types.clear();
  filter_context.SetMimeType("other/mime");
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(2U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
}
#endif

TEST(FilterTest, Svgz) {
  MockFilterContext filter_context;

  // Check that svgz files are only decompressed when not downloading.
  const std::string kSvgzMime("image/svg+xml");
  const std::string kSvgzUrl("http://ignore.com/foo.svgz");
  const std::string kSvgUrl("http://ignore.com/foo.svg");
  std::vector<Filter::FilterType> encoding_types;

  // Test svgz extension
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kSvgzMime);
  filter_context.SetURL(GURL(kSvgzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(true);
  filter_context.SetMimeType(kSvgzMime);
  filter_context.SetURL(GURL(kSvgzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  EXPECT_TRUE(encoding_types.empty());

  // Test svg extension
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kSvgzMime);
  filter_context.SetURL(GURL(kSvgUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(true);
  filter_context.SetMimeType(kSvgzMime);
  filter_context.SetURL(GURL(kSvgUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
}

TEST(FilterTest, UnsupportedMimeGzip) {
  // From issue 8170 - handling files with Content-Encoding: x-gzip
  MockFilterContext filter_context;
  std::vector<Filter::FilterType> encoding_types;
  const std::string kTarMime("application/x-tar");
  const std::string kCpioMime("application/x-cpio");
  const std::string kTarUrl("http://ignore.com/foo.tar");
  const std::string kTargzUrl("http://ignore.com/foo.tar.gz");
  const std::string kTgzUrl("http://ignore.com/foo.tgz");
  const std::string kBadTgzUrl("http://ignore.com/foo.targz");
  const std::string kUrl("http://ignore.com/foo");

  // Firefox 3 does not decompress when we have unsupported mime types for
  // certain filenames.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kTarMime);
  filter_context.SetURL(GURL(kTargzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  EXPECT_TRUE(encoding_types.empty());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kTarMime);
  filter_context.SetURL(GURL(kTgzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  EXPECT_TRUE(encoding_types.empty());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kCpioMime);
  filter_context.SetURL(GURL(kTgzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  EXPECT_TRUE(encoding_types.empty());

  // Same behavior for downloads.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(true);
  filter_context.SetMimeType(kCpioMime);
  filter_context.SetURL(GURL(kTgzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  EXPECT_TRUE(encoding_types.empty());

  // Unsupported mime type with wrong file name, decompressed.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kTarMime);
  filter_context.SetURL(GURL(kUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kTarMime);
  filter_context.SetURL(GURL(kTarUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kTarMime);
  filter_context.SetURL(GURL(kBadTgzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());

  // Same behavior for downloads.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(true);
  filter_context.SetMimeType(kTarMime);
  filter_context.SetURL(GURL(kBadTgzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
}

TEST(FilterTest, SupportedMimeGzip) {
  // From issue 16430 - Files with supported mime types should be decompressed,
  // even though these files end in .gz/.tgz.
  MockFilterContext filter_context;
  std::vector<Filter::FilterType> encoding_types;
  const std::string kGzUrl("http://ignore.com/foo.gz");
  const std::string kUrl("http://ignore.com/foo");
  const std::string kHtmlMime("text/html");
  const std::string kJavascriptMime("text/javascript");

  // For files that does not end in .gz/.tgz, we always decompress.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kHtmlMime);
  filter_context.SetURL(GURL(kUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(true);
  filter_context.SetMimeType(kHtmlMime);
  filter_context.SetURL(GURL(kUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());

  // And also decompress files that end in .gz/.tgz.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kHtmlMime);
  filter_context.SetURL(GURL(kGzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());

  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(false);
  filter_context.SetMimeType(kJavascriptMime);
  filter_context.SetURL(GURL(kGzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  ASSERT_EQ(1U, encoding_types.size());
  EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());

  // Except on downloads, where they just get saved.
  encoding_types.clear();
  encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
  filter_context.SetDownload(true);
  filter_context.SetMimeType(kHtmlMime);
  filter_context.SetURL(GURL(kGzUrl));
  Filter::FixupEncodingTypes(filter_context, &encoding_types);
  EXPECT_TRUE(encoding_types.empty());
}

}  // namespace net
