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
, SdchEncoding
) {
86 // Handle content encodings including SDCH.
87 const std::string
kTextHtmlMime("text/html");
88 MockFilterContext filter_context
;
89 filter_context
.SetSdchResponse(true);
91 std::vector
<Filter::FilterType
> encoding_types
;
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]);
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]);
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]);
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);
128 std::vector
<Filter::FilterType
> encoding_types
;
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]);
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]);
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]);
159 TEST(FilterTest
, Svgz
) {
160 MockFilterContext filter_context
;
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
;
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());
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());
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());
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());
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");
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());
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());
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());
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());
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());
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());
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());
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());
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");
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());
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());
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());
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());
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());