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.
5 #include "net/filter/filter.h"
6 #include "net/filter/mock_filter_context.h"
7 #include "testing/gtest/include/gtest/gtest.h"
11 class FilterTest
: public testing::Test
{
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"));
38 // Check various fixups that modify content encoding lists.
39 TEST(FilterTest
, ApacheGzip
) {
40 MockFilterContext filter_context
;
41 filter_context
.SetSdchResponse(false);
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
;
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());
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());
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());
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());
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());
85 TEST(FilterTest
, GzipContentDispositionFilename
) {
86 MockFilterContext filter_context
;
87 filter_context
.SetSdchResponse(false);
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
;
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());
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);
108 std::vector
<Filter::FilterType
> encoding_types
;
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]);
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]);
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]);
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);
145 std::vector
<Filter::FilterType
> encoding_types
;
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]);
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]);
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]);
176 TEST(FilterTest
, Svgz
) {
177 MockFilterContext filter_context
;
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
;
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());
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());
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());
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());
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");
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());
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());
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());
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());
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());
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());
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());
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());
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");
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());
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());
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());
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());
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());