• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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/filter/filter.h"
6 #include "net/filter/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 
TEST(FilterTest,ContentTypeId)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.
TEST(FilterTest,ApacheGzip)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 
TEST(FilterTest,GzipContentDispositionFilename)85 TEST(FilterTest, GzipContentDispositionFilename) {
86   MockFilterContext filter_context;
87   filter_context.SetSdchResponse(false);
88 
89   const std::string kGzipMime("application/x-tar");
90   const std::string kContentDisposition("attachment; filename=\"foo.tgz\"");
91   const std::string kURL("http://foo.com/getfoo.php");
92   std::vector<Filter::FilterType> encoding_types;
93 
94   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
95   filter_context.SetMimeType(kGzipMime);
96   filter_context.SetURL(GURL(kURL));
97   filter_context.SetContentDisposition(kContentDisposition);
98   Filter::FixupEncodingTypes(filter_context, &encoding_types);
99   ASSERT_EQ(0U, encoding_types.size());
100 }
101 
TEST(FilterTest,SdchEncoding)102 TEST(FilterTest, SdchEncoding) {
103   // Handle content encodings including SDCH.
104   const std::string kTextHtmlMime("text/html");
105   MockFilterContext filter_context;
106   filter_context.SetSdchResponse(true);
107 
108   std::vector<Filter::FilterType> encoding_types;
109 
110   // Check for most common encoding, and verify it survives unchanged.
111   encoding_types.clear();
112   encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
113   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
114   filter_context.SetMimeType(kTextHtmlMime);
115   Filter::FixupEncodingTypes(filter_context, &encoding_types);
116   ASSERT_EQ(2U, encoding_types.size());
117   EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
118   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
119 
120   // Unchanged even with other mime types.
121   encoding_types.clear();
122   encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
123   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
124   filter_context.SetMimeType("other/type");
125   Filter::FixupEncodingTypes(filter_context, &encoding_types);
126   ASSERT_EQ(2U, encoding_types.size());
127   EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
128   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
129 
130   // Solo SDCH is extended to include optional gunzip.
131   encoding_types.clear();
132   encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
133   Filter::FixupEncodingTypes(filter_context, &encoding_types);
134   ASSERT_EQ(2U, encoding_types.size());
135   EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
136   EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
137 }
138 
TEST(FilterTest,MissingSdchEncoding)139 TEST(FilterTest, MissingSdchEncoding) {
140   // Handle interesting case where entire SDCH encoding assertion "got lost."
141   const std::string kTextHtmlMime("text/html");
142   MockFilterContext filter_context;
143   filter_context.SetSdchResponse(true);
144 
145   std::vector<Filter::FilterType> encoding_types;
146 
147   // Loss of encoding, but it was an SDCH response with html type.
148   encoding_types.clear();
149   filter_context.SetMimeType(kTextHtmlMime);
150   Filter::FixupEncodingTypes(filter_context, &encoding_types);
151   ASSERT_EQ(2U, encoding_types.size());
152   EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
153   EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
154 
155   // Loss of encoding, but it was an SDCH response with a prefix that says it
156   // was an html type.  Note that it *should* be the case that a precise match
157   // with "text/html" we be collected by GetMimeType() and passed in, but we
158   // coded the fixup defensively (scanning for a prefix of "text/html", so this
159   // is an example which could survive such confusion in the caller).
160   encoding_types.clear();
161   filter_context.SetMimeType("text/html; charset=UTF-8");
162   Filter::FixupEncodingTypes(filter_context, &encoding_types);
163   ASSERT_EQ(2U, encoding_types.size());
164   EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
165   EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
166 
167   // No encoding, but it was an SDCH response with non-html type.
168   encoding_types.clear();
169   filter_context.SetMimeType("other/mime");
170   Filter::FixupEncodingTypes(filter_context, &encoding_types);
171   ASSERT_EQ(2U, encoding_types.size());
172   EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
173   EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
174 }
175 
TEST(FilterTest,Svgz)176 TEST(FilterTest, Svgz) {
177   MockFilterContext filter_context;
178 
179   // Check that svgz files are only decompressed when not downloading.
180   const std::string kSvgzMime("image/svg+xml");
181   const std::string kSvgzUrl("http://ignore.com/foo.svgz");
182   const std::string kSvgUrl("http://ignore.com/foo.svg");
183   std::vector<Filter::FilterType> encoding_types;
184 
185   // Test svgz extension
186   encoding_types.clear();
187   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
188   filter_context.SetDownload(false);
189   filter_context.SetMimeType(kSvgzMime);
190   filter_context.SetURL(GURL(kSvgzUrl));
191   Filter::FixupEncodingTypes(filter_context, &encoding_types);
192   ASSERT_EQ(1U, encoding_types.size());
193   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
194 
195   encoding_types.clear();
196   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
197   filter_context.SetDownload(true);
198   filter_context.SetMimeType(kSvgzMime);
199   filter_context.SetURL(GURL(kSvgzUrl));
200   Filter::FixupEncodingTypes(filter_context, &encoding_types);
201   EXPECT_TRUE(encoding_types.empty());
202 
203   // Test svg extension
204   encoding_types.clear();
205   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
206   filter_context.SetDownload(false);
207   filter_context.SetMimeType(kSvgzMime);
208   filter_context.SetURL(GURL(kSvgUrl));
209   Filter::FixupEncodingTypes(filter_context, &encoding_types);
210   ASSERT_EQ(1U, encoding_types.size());
211   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
212 
213   encoding_types.clear();
214   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
215   filter_context.SetDownload(true);
216   filter_context.SetMimeType(kSvgzMime);
217   filter_context.SetURL(GURL(kSvgUrl));
218   Filter::FixupEncodingTypes(filter_context, &encoding_types);
219   ASSERT_EQ(1U, encoding_types.size());
220   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
221 }
222 
TEST(FilterTest,UnsupportedMimeGzip)223 TEST(FilterTest, UnsupportedMimeGzip) {
224   // From issue 8170 - handling files with Content-Encoding: x-gzip
225   MockFilterContext filter_context;
226   std::vector<Filter::FilterType> encoding_types;
227   const std::string kTarMime("application/x-tar");
228   const std::string kCpioMime("application/x-cpio");
229   const std::string kTarUrl("http://ignore.com/foo.tar");
230   const std::string kTargzUrl("http://ignore.com/foo.tar.gz");
231   const std::string kTgzUrl("http://ignore.com/foo.tgz");
232   const std::string kBadTgzUrl("http://ignore.com/foo.targz");
233   const std::string kUrl("http://ignore.com/foo");
234 
235   // Firefox 3 does not decompress when we have unsupported mime types for
236   // certain filenames.
237   encoding_types.clear();
238   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
239   filter_context.SetDownload(false);
240   filter_context.SetMimeType(kTarMime);
241   filter_context.SetURL(GURL(kTargzUrl));
242   Filter::FixupEncodingTypes(filter_context, &encoding_types);
243   EXPECT_TRUE(encoding_types.empty());
244 
245   encoding_types.clear();
246   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
247   filter_context.SetDownload(false);
248   filter_context.SetMimeType(kTarMime);
249   filter_context.SetURL(GURL(kTgzUrl));
250   Filter::FixupEncodingTypes(filter_context, &encoding_types);
251   EXPECT_TRUE(encoding_types.empty());
252 
253   encoding_types.clear();
254   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
255   filter_context.SetDownload(false);
256   filter_context.SetMimeType(kCpioMime);
257   filter_context.SetURL(GURL(kTgzUrl));
258   Filter::FixupEncodingTypes(filter_context, &encoding_types);
259   EXPECT_TRUE(encoding_types.empty());
260 
261   // Same behavior for downloads.
262   encoding_types.clear();
263   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
264   filter_context.SetDownload(true);
265   filter_context.SetMimeType(kCpioMime);
266   filter_context.SetURL(GURL(kTgzUrl));
267   Filter::FixupEncodingTypes(filter_context, &encoding_types);
268   EXPECT_TRUE(encoding_types.empty());
269 
270   // Unsupported mime type with wrong file name, decompressed.
271   encoding_types.clear();
272   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
273   filter_context.SetDownload(false);
274   filter_context.SetMimeType(kTarMime);
275   filter_context.SetURL(GURL(kUrl));
276   Filter::FixupEncodingTypes(filter_context, &encoding_types);
277   ASSERT_EQ(1U, encoding_types.size());
278   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
279 
280   encoding_types.clear();
281   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
282   filter_context.SetDownload(false);
283   filter_context.SetMimeType(kTarMime);
284   filter_context.SetURL(GURL(kTarUrl));
285   Filter::FixupEncodingTypes(filter_context, &encoding_types);
286   ASSERT_EQ(1U, encoding_types.size());
287   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
288 
289   encoding_types.clear();
290   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
291   filter_context.SetDownload(false);
292   filter_context.SetMimeType(kTarMime);
293   filter_context.SetURL(GURL(kBadTgzUrl));
294   Filter::FixupEncodingTypes(filter_context, &encoding_types);
295   ASSERT_EQ(1U, encoding_types.size());
296   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
297 
298   // Same behavior for downloads.
299   encoding_types.clear();
300   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
301   filter_context.SetDownload(true);
302   filter_context.SetMimeType(kTarMime);
303   filter_context.SetURL(GURL(kBadTgzUrl));
304   Filter::FixupEncodingTypes(filter_context, &encoding_types);
305   ASSERT_EQ(1U, encoding_types.size());
306   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
307 }
308 
TEST(FilterTest,SupportedMimeGzip)309 TEST(FilterTest, SupportedMimeGzip) {
310   // From issue 16430 - Files with supported mime types should be decompressed,
311   // even though these files end in .gz/.tgz.
312   MockFilterContext filter_context;
313   std::vector<Filter::FilterType> encoding_types;
314   const std::string kGzUrl("http://ignore.com/foo.gz");
315   const std::string kUrl("http://ignore.com/foo");
316   const std::string kHtmlMime("text/html");
317   const std::string kJavascriptMime("text/javascript");
318 
319   // For files that does not end in .gz/.tgz, we always decompress.
320   encoding_types.clear();
321   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
322   filter_context.SetDownload(false);
323   filter_context.SetMimeType(kHtmlMime);
324   filter_context.SetURL(GURL(kUrl));
325   Filter::FixupEncodingTypes(filter_context, &encoding_types);
326   ASSERT_EQ(1U, encoding_types.size());
327   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
328 
329   encoding_types.clear();
330   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
331   filter_context.SetDownload(true);
332   filter_context.SetMimeType(kHtmlMime);
333   filter_context.SetURL(GURL(kUrl));
334   Filter::FixupEncodingTypes(filter_context, &encoding_types);
335   ASSERT_EQ(1U, encoding_types.size());
336   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
337 
338   // And also decompress files that end in .gz/.tgz.
339   encoding_types.clear();
340   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
341   filter_context.SetDownload(false);
342   filter_context.SetMimeType(kHtmlMime);
343   filter_context.SetURL(GURL(kGzUrl));
344   Filter::FixupEncodingTypes(filter_context, &encoding_types);
345   ASSERT_EQ(1U, encoding_types.size());
346   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
347 
348   encoding_types.clear();
349   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
350   filter_context.SetDownload(false);
351   filter_context.SetMimeType(kJavascriptMime);
352   filter_context.SetURL(GURL(kGzUrl));
353   Filter::FixupEncodingTypes(filter_context, &encoding_types);
354   ASSERT_EQ(1U, encoding_types.size());
355   EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
356 
357   // Except on downloads, where they just get saved.
358   encoding_types.clear();
359   encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
360   filter_context.SetDownload(true);
361   filter_context.SetMimeType(kHtmlMime);
362   filter_context.SetURL(GURL(kGzUrl));
363   Filter::FixupEncodingTypes(filter_context, &encoding_types);
364   EXPECT_TRUE(encoding_types.empty());
365 }
366 
367 }  // namespace net
368