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