Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/base/filter.h"
      6 #include "net/base/mock_filter_context.h"
      7 #include "testing/gtest/include/gtest/gtest.h"
      8 
      9 namespace net {
     10 
     11 class FilterTest : public testing::Test {
     12 };
     13 
     14 TEST(FilterTest, ContentTypeId) {
     15   // Check for basic translation of Content-Encoding, including case variations.
     16   EXPECT_EQ(Filter::FILTER_TYPE_DEFLATE,
     17             Filter::ConvertEncodingToType("deflate"));
     18   EXPECT_EQ(Filter::FILTER_TYPE_DEFLATE,
     19             Filter::ConvertEncodingToType("deflAte"));
     20   EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
     21             Filter::ConvertEncodingToType("gzip"));
     22   EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
     23             Filter::ConvertEncodingToType("GzIp"));
     24   EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
     25             Filter::ConvertEncodingToType("x-gzip"));
     26   EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
     27             Filter::ConvertEncodingToType("X-GzIp"));
     28   EXPECT_EQ(Filter::FILTER_TYPE_SDCH,
     29             Filter::ConvertEncodingToType("sdch"));
     30   EXPECT_EQ(Filter::FILTER_TYPE_SDCH,
     31             Filter::ConvertEncodingToType("sDcH"));
     32   EXPECT_EQ(Filter::FILTER_TYPE_UNSUPPORTED,
     33             Filter::ConvertEncodingToType("weird"));
     34   EXPECT_EQ(Filter::FILTER_TYPE_UNSUPPORTED,
     35             Filter::ConvertEncodingToType("strange"));
     36 }
     37 
     38 // Check various fixups that modify content encoding lists.
     39 TEST(FilterTest, ApacheGzip) {
     40   MockFilterContext filter_context;
     41   filter_context.SetSdchResponse(false);
     42 
     43   // Check that redundant gzip mime type removes only solo gzip encoding.
     44   const std::string kGzipMime1("application/x-gzip");
     45   const std::string kGzipMime2("application/gzip");
     46   const std::string kGzipMime3("application/x-gunzip");
     47   std::vector<Filter::FilterType> encoding_types;
     48 
     49   // First show it removes the gzip, given any gzip style mime type.
     50   encoding_types.clear();
     51   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
     52   filter_context.SetMimeType(kGzipMime1);
     53   Filter::FixupEncodingTypes(filter_context, &encoding_types);
     54   EXPECT_TRUE(encoding_types.empty());
     55 
     56   encoding_types.clear();
     57   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
     58   filter_context.SetMimeType(kGzipMime2);
     59   Filter::FixupEncodingTypes(filter_context, &encoding_types);
     60   EXPECT_TRUE(encoding_types.empty());
     61 
     62   encoding_types.clear();
     63   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
     64   filter_context.SetMimeType(kGzipMime3);
     65   Filter::FixupEncodingTypes(filter_context, &encoding_types);
     66   EXPECT_TRUE(encoding_types.empty());
     67 
     68   // Check to be sure it doesn't remove everything when it has such a type.
     69   encoding_types.clear();
     70   encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
     71   filter_context.SetMimeType(kGzipMime1);
     72   Filter::FixupEncodingTypes(filter_context, &encoding_types);
     73   ASSERT_EQ(1U, encoding_types.size());
     74   EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types.front());
     75 
     76   // Check to be sure that gzip can survive with other mime types.
     77   encoding_types.clear();
     78   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
     79   filter_context.SetMimeType("other/mime");
     80   Filter::FixupEncodingTypes(filter_context, &encoding_types);
     81   ASSERT_EQ(1U, encoding_types.size());
     82   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
     83 }
     84 
     85 TEST(FilterTest, SdchEncoding) {
     86   // Handle content encodings including SDCH.
     87   const std::string kTextHtmlMime("text/html");
     88   MockFilterContext filter_context;
     89   filter_context.SetSdchResponse(true);
     90 
     91   std::vector<Filter::FilterType> encoding_types;
     92 
     93   // Check for most common encoding, and verify it survives unchanged.
     94   encoding_types.clear();
     95   encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
     96   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
     97   filter_context.SetMimeType(kTextHtmlMime);
     98   Filter::FixupEncodingTypes(filter_context, &encoding_types);
     99   ASSERT_EQ(2U, encoding_types.size());
    100   EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
    101   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
    102 
    103   // Unchanged even with other mime types.
    104   encoding_types.clear();
    105   encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
    106   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    107   filter_context.SetMimeType("other/type");
    108   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    109   ASSERT_EQ(2U, encoding_types.size());
    110   EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
    111   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
    112 
    113   // Solo SDCH is extended to include optional gunzip.
    114   encoding_types.clear();
    115   encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
    116   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    117   ASSERT_EQ(2U, encoding_types.size());
    118   EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
    119   EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
    120 }
    121 
    122 TEST(FilterTest, MissingSdchEncoding) {
    123   // Handle interesting case where entire SDCH encoding assertion "got lost."
    124   const std::string kTextHtmlMime("text/html");
    125   MockFilterContext filter_context;
    126   filter_context.SetSdchResponse(true);
    127 
    128   std::vector<Filter::FilterType> encoding_types;
    129 
    130   // Loss of encoding, but it was an SDCH response with html type.
    131   encoding_types.clear();
    132   filter_context.SetMimeType(kTextHtmlMime);
    133   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    134   ASSERT_EQ(2U, encoding_types.size());
    135   EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
    136   EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
    137 
    138   // Loss of encoding, but it was an SDCH response with a prefix that says it
    139   // was an html type.  Note that it *should* be the case that a precise match
    140   // with "text/html" we be collected by GetMimeType() and passed in, but we
    141   // coded the fixup defensively (scanning for a prefix of "text/html", so this
    142   // is an example which could survive such confusion in the caller).
    143   encoding_types.clear();
    144   filter_context.SetMimeType("text/html; charset=UTF-8");
    145   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    146   ASSERT_EQ(2U, encoding_types.size());
    147   EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
    148   EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
    149 
    150   // No encoding, but it was an SDCH response with non-html type.
    151   encoding_types.clear();
    152   filter_context.SetMimeType("other/mime");
    153   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    154   ASSERT_EQ(2U, encoding_types.size());
    155   EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
    156   EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
    157 }
    158 
    159 TEST(FilterTest, Svgz) {
    160   MockFilterContext filter_context;
    161 
    162   // Check that svgz files are only decompressed when not downloading.
    163   const std::string kSvgzMime("image/svg+xml");
    164   const std::string kSvgzUrl("http://ignore.com/foo.svgz");
    165   const std::string kSvgUrl("http://ignore.com/foo.svg");
    166   std::vector<Filter::FilterType> encoding_types;
    167 
    168   // Test svgz extension
    169   encoding_types.clear();
    170   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    171   filter_context.SetDownload(false);
    172   filter_context.SetMimeType(kSvgzMime);
    173   filter_context.SetURL(GURL(kSvgzUrl));
    174   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    175   ASSERT_EQ(1U, encoding_types.size());
    176   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    177 
    178   encoding_types.clear();
    179   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    180   filter_context.SetDownload(true);
    181   filter_context.SetMimeType(kSvgzMime);
    182   filter_context.SetURL(GURL(kSvgzUrl));
    183   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    184   EXPECT_TRUE(encoding_types.empty());
    185 
    186   // Test svg extension
    187   encoding_types.clear();
    188   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    189   filter_context.SetDownload(false);
    190   filter_context.SetMimeType(kSvgzMime);
    191   filter_context.SetURL(GURL(kSvgUrl));
    192   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    193   ASSERT_EQ(1U, encoding_types.size());
    194   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    195 
    196   encoding_types.clear();
    197   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    198   filter_context.SetDownload(true);
    199   filter_context.SetMimeType(kSvgzMime);
    200   filter_context.SetURL(GURL(kSvgUrl));
    201   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    202   ASSERT_EQ(1U, encoding_types.size());
    203   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    204 }
    205 
    206 TEST(FilterTest, UnsupportedMimeGzip) {
    207   // From issue 8170 - handling files with Content-Encoding: x-gzip
    208   MockFilterContext filter_context;
    209   std::vector<Filter::FilterType> encoding_types;
    210   const std::string kTarMime("application/x-tar");
    211   const std::string kCpioMime("application/x-cpio");
    212   const std::string kTarUrl("http://ignore.com/foo.tar");
    213   const std::string kTargzUrl("http://ignore.com/foo.tar.gz");
    214   const std::string kTgzUrl("http://ignore.com/foo.tgz");
    215   const std::string kBadTgzUrl("http://ignore.com/foo.targz");
    216   const std::string kUrl("http://ignore.com/foo");
    217 
    218   // Firefox 3 does not decompress when we have unsupported mime types for
    219   // certain filenames.
    220   encoding_types.clear();
    221   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    222   filter_context.SetDownload(false);
    223   filter_context.SetMimeType(kTarMime);
    224   filter_context.SetURL(GURL(kTargzUrl));
    225   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    226   EXPECT_TRUE(encoding_types.empty());
    227 
    228   encoding_types.clear();
    229   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    230   filter_context.SetDownload(false);
    231   filter_context.SetMimeType(kTarMime);
    232   filter_context.SetURL(GURL(kTgzUrl));
    233   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    234   EXPECT_TRUE(encoding_types.empty());
    235 
    236   encoding_types.clear();
    237   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    238   filter_context.SetDownload(false);
    239   filter_context.SetMimeType(kCpioMime);
    240   filter_context.SetURL(GURL(kTgzUrl));
    241   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    242   EXPECT_TRUE(encoding_types.empty());
    243 
    244   // Same behavior for downloads.
    245   encoding_types.clear();
    246   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    247   filter_context.SetDownload(true);
    248   filter_context.SetMimeType(kCpioMime);
    249   filter_context.SetURL(GURL(kTgzUrl));
    250   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    251   EXPECT_TRUE(encoding_types.empty());
    252 
    253   // Unsupported mime type with wrong file name, decompressed.
    254   encoding_types.clear();
    255   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    256   filter_context.SetDownload(false);
    257   filter_context.SetMimeType(kTarMime);
    258   filter_context.SetURL(GURL(kUrl));
    259   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    260   ASSERT_EQ(1U, encoding_types.size());
    261   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    262 
    263   encoding_types.clear();
    264   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    265   filter_context.SetDownload(false);
    266   filter_context.SetMimeType(kTarMime);
    267   filter_context.SetURL(GURL(kTarUrl));
    268   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    269   ASSERT_EQ(1U, encoding_types.size());
    270   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    271 
    272   encoding_types.clear();
    273   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    274   filter_context.SetDownload(false);
    275   filter_context.SetMimeType(kTarMime);
    276   filter_context.SetURL(GURL(kBadTgzUrl));
    277   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    278   ASSERT_EQ(1U, encoding_types.size());
    279   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    280 
    281   // Same behavior for downloads.
    282   encoding_types.clear();
    283   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    284   filter_context.SetDownload(true);
    285   filter_context.SetMimeType(kTarMime);
    286   filter_context.SetURL(GURL(kBadTgzUrl));
    287   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    288   ASSERT_EQ(1U, encoding_types.size());
    289   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    290 }
    291 
    292 TEST(FilterTest, SupportedMimeGzip) {
    293   // From issue 16430 - Files with supported mime types should be decompressed,
    294   // even though these files end in .gz/.tgz.
    295   MockFilterContext filter_context;
    296   std::vector<Filter::FilterType> encoding_types;
    297   const std::string kGzUrl("http://ignore.com/foo.gz");
    298   const std::string kUrl("http://ignore.com/foo");
    299   const std::string kHtmlMime("text/html");
    300   const std::string kJavascriptMime("text/javascript");
    301 
    302   // For files that does not end in .gz/.tgz, we always decompress.
    303   encoding_types.clear();
    304   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    305   filter_context.SetDownload(false);
    306   filter_context.SetMimeType(kHtmlMime);
    307   filter_context.SetURL(GURL(kUrl));
    308   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    309   ASSERT_EQ(1U, encoding_types.size());
    310   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    311 
    312   encoding_types.clear();
    313   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    314   filter_context.SetDownload(true);
    315   filter_context.SetMimeType(kHtmlMime);
    316   filter_context.SetURL(GURL(kUrl));
    317   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    318   ASSERT_EQ(1U, encoding_types.size());
    319   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    320 
    321   // And also decompress files that end in .gz/.tgz.
    322   encoding_types.clear();
    323   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    324   filter_context.SetDownload(false);
    325   filter_context.SetMimeType(kHtmlMime);
    326   filter_context.SetURL(GURL(kGzUrl));
    327   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    328   ASSERT_EQ(1U, encoding_types.size());
    329   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    330 
    331   encoding_types.clear();
    332   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    333   filter_context.SetDownload(false);
    334   filter_context.SetMimeType(kJavascriptMime);
    335   filter_context.SetURL(GURL(kGzUrl));
    336   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    337   ASSERT_EQ(1U, encoding_types.size());
    338   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
    339 
    340   // Except on downloads, where they just get saved.
    341   encoding_types.clear();
    342   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
    343   filter_context.SetDownload(true);
    344   filter_context.SetMimeType(kHtmlMime);
    345   filter_context.SetURL(GURL(kGzUrl));
    346   Filter::FixupEncodingTypes(filter_context, &encoding_types);
    347   EXPECT_TRUE(encoding_types.empty());
    348 }
    349 
    350 }  // namespace net
    351