Move GetProcessIntegrityLevel to file_info.h and remove the handle argument.
[chromium-blink-merge.git] / net / filter / filter_unittest.cc
blobfcedeaf3bc40de1d4c9233d7e44e2e84313d8c50
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/base/io_buffer.h"
6 #include "net/filter/filter.h"
7 #include "net/filter/mock_filter_context.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 namespace net {
12 namespace {
14 class PassThroughFilter : public Filter {
15 public:
16 PassThroughFilter() : Filter(FILTER_TYPE_UNSUPPORTED) {}
18 FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) override {
19 return CopyOut(dest_buffer, dest_len);
22 DISALLOW_COPY_AND_ASSIGN(PassThroughFilter);
25 } // namespace
27 TEST(FilterTest, ContentTypeId) {
28 // Check for basic translation of Content-Encoding, including case variations.
29 EXPECT_EQ(Filter::FILTER_TYPE_DEFLATE,
30 Filter::ConvertEncodingToType("deflate"));
31 EXPECT_EQ(Filter::FILTER_TYPE_DEFLATE,
32 Filter::ConvertEncodingToType("deflAte"));
33 EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
34 Filter::ConvertEncodingToType("gzip"));
35 EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
36 Filter::ConvertEncodingToType("GzIp"));
37 EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
38 Filter::ConvertEncodingToType("x-gzip"));
39 EXPECT_EQ(Filter::FILTER_TYPE_GZIP,
40 Filter::ConvertEncodingToType("X-GzIp"));
41 EXPECT_EQ(Filter::FILTER_TYPE_SDCH,
42 Filter::ConvertEncodingToType("sdch"));
43 EXPECT_EQ(Filter::FILTER_TYPE_SDCH,
44 Filter::ConvertEncodingToType("sDcH"));
45 EXPECT_EQ(Filter::FILTER_TYPE_UNSUPPORTED,
46 Filter::ConvertEncodingToType("weird"));
47 EXPECT_EQ(Filter::FILTER_TYPE_UNSUPPORTED,
48 Filter::ConvertEncodingToType("strange"));
51 // Check various fixups that modify content encoding lists.
52 TEST(FilterTest, ApacheGzip) {
53 MockFilterContext filter_context;
54 filter_context.SetSdchResponse(NULL);
56 // Check that redundant gzip mime type removes only solo gzip encoding.
57 const std::string kGzipMime1("application/x-gzip");
58 const std::string kGzipMime2("application/gzip");
59 const std::string kGzipMime3("application/x-gunzip");
60 std::vector<Filter::FilterType> encoding_types;
62 // First show it removes the gzip, given any gzip style mime type.
63 encoding_types.clear();
64 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
65 filter_context.SetMimeType(kGzipMime1);
66 Filter::FixupEncodingTypes(filter_context, &encoding_types);
67 EXPECT_TRUE(encoding_types.empty());
69 encoding_types.clear();
70 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
71 filter_context.SetMimeType(kGzipMime2);
72 Filter::FixupEncodingTypes(filter_context, &encoding_types);
73 EXPECT_TRUE(encoding_types.empty());
75 encoding_types.clear();
76 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
77 filter_context.SetMimeType(kGzipMime3);
78 Filter::FixupEncodingTypes(filter_context, &encoding_types);
79 EXPECT_TRUE(encoding_types.empty());
81 // Check to be sure it doesn't remove everything when it has such a type.
82 encoding_types.clear();
83 encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
84 filter_context.SetMimeType(kGzipMime1);
85 Filter::FixupEncodingTypes(filter_context, &encoding_types);
86 ASSERT_EQ(1U, encoding_types.size());
87 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types.front());
89 // Check to be sure that gzip can survive with other mime types.
90 encoding_types.clear();
91 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
92 filter_context.SetMimeType("other/mime");
93 Filter::FixupEncodingTypes(filter_context, &encoding_types);
94 ASSERT_EQ(1U, encoding_types.size());
95 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
98 TEST(FilterTest, GzipContentDispositionFilename) {
99 MockFilterContext filter_context;
100 filter_context.SetSdchResponse(NULL);
102 const std::string kGzipMime("application/x-tar");
103 const std::string kContentDisposition("attachment; filename=\"foo.tgz\"");
104 const std::string kURL("http://foo.com/getfoo.php");
105 std::vector<Filter::FilterType> encoding_types;
107 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
108 filter_context.SetMimeType(kGzipMime);
109 filter_context.SetURL(GURL(kURL));
110 filter_context.SetContentDisposition(kContentDisposition);
111 Filter::FixupEncodingTypes(filter_context, &encoding_types);
112 ASSERT_EQ(0U, encoding_types.size());
115 TEST(FilterTest, SdchEncoding) {
116 // Handle content encodings including SDCH.
117 const std::string kTextHtmlMime("text/html");
118 MockFilterContext filter_context;
119 // Empty handle indicates to filter that SDCH is active.
120 filter_context.SetSdchResponse(
121 SdchManager::CreateEmptyDictionarySetForTesting().Pass());
123 std::vector<Filter::FilterType> encoding_types;
125 // Check for most common encoding, and verify it survives unchanged.
126 encoding_types.clear();
127 encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
128 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
129 filter_context.SetMimeType(kTextHtmlMime);
130 Filter::FixupEncodingTypes(filter_context, &encoding_types);
131 ASSERT_EQ(2U, encoding_types.size());
132 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
133 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
135 // Unchanged even with other mime types.
136 encoding_types.clear();
137 encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
138 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
139 filter_context.SetMimeType("other/type");
140 Filter::FixupEncodingTypes(filter_context, &encoding_types);
141 ASSERT_EQ(2U, encoding_types.size());
142 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
143 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
145 // Solo SDCH is extended to include optional gunzip.
146 encoding_types.clear();
147 encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
148 Filter::FixupEncodingTypes(filter_context, &encoding_types);
149 ASSERT_EQ(2U, encoding_types.size());
150 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
151 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
154 TEST(FilterTest, MissingSdchEncoding) {
155 // Handle interesting case where entire SDCH encoding assertion "got lost."
156 const std::string kTextHtmlMime("text/html");
157 MockFilterContext filter_context;
158 filter_context.SetSdchResponse(
159 SdchManager::CreateEmptyDictionarySetForTesting().Pass());
161 std::vector<Filter::FilterType> encoding_types;
163 // Loss of encoding, but it was an SDCH response with html type.
164 encoding_types.clear();
165 filter_context.SetMimeType(kTextHtmlMime);
166 Filter::FixupEncodingTypes(filter_context, &encoding_types);
167 ASSERT_EQ(2U, encoding_types.size());
168 EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
169 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
171 // Loss of encoding, but it was an SDCH response with a prefix that says it
172 // was an html type. Note that it *should* be the case that a precise match
173 // with "text/html" we be collected by GetMimeType() and passed in, but we
174 // coded the fixup defensively (scanning for a prefix of "text/html", so this
175 // is an example which could survive such confusion in the caller).
176 encoding_types.clear();
177 filter_context.SetMimeType("text/html; charset=UTF-8");
178 Filter::FixupEncodingTypes(filter_context, &encoding_types);
179 ASSERT_EQ(2U, encoding_types.size());
180 EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
181 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
183 // No encoding, but it was an SDCH response with non-html type.
184 encoding_types.clear();
185 filter_context.SetMimeType("other/mime");
186 Filter::FixupEncodingTypes(filter_context, &encoding_types);
187 ASSERT_EQ(2U, encoding_types.size());
188 EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
189 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
192 TEST(FilterTest, Svgz) {
193 MockFilterContext filter_context;
195 // Check that svgz files are only decompressed when not downloading.
196 const std::string kSvgzMime("image/svg+xml");
197 const std::string kSvgzUrl("http://ignore.com/foo.svgz");
198 const std::string kSvgUrl("http://ignore.com/foo.svg");
199 std::vector<Filter::FilterType> encoding_types;
201 // Test svgz extension
202 encoding_types.clear();
203 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
204 filter_context.SetDownload(false);
205 filter_context.SetMimeType(kSvgzMime);
206 filter_context.SetURL(GURL(kSvgzUrl));
207 Filter::FixupEncodingTypes(filter_context, &encoding_types);
208 ASSERT_EQ(1U, encoding_types.size());
209 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
211 encoding_types.clear();
212 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
213 filter_context.SetDownload(true);
214 filter_context.SetMimeType(kSvgzMime);
215 filter_context.SetURL(GURL(kSvgzUrl));
216 Filter::FixupEncodingTypes(filter_context, &encoding_types);
217 EXPECT_TRUE(encoding_types.empty());
219 // Test svg extension
220 encoding_types.clear();
221 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
222 filter_context.SetDownload(false);
223 filter_context.SetMimeType(kSvgzMime);
224 filter_context.SetURL(GURL(kSvgUrl));
225 Filter::FixupEncodingTypes(filter_context, &encoding_types);
226 ASSERT_EQ(1U, encoding_types.size());
227 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
229 encoding_types.clear();
230 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
231 filter_context.SetDownload(true);
232 filter_context.SetMimeType(kSvgzMime);
233 filter_context.SetURL(GURL(kSvgUrl));
234 Filter::FixupEncodingTypes(filter_context, &encoding_types);
235 ASSERT_EQ(1U, encoding_types.size());
236 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
239 TEST(FilterTest, UnsupportedMimeGzip) {
240 // From issue 8170 - handling files with Content-Encoding: x-gzip
241 MockFilterContext filter_context;
242 std::vector<Filter::FilterType> encoding_types;
243 const std::string kTarMime("application/x-tar");
244 const std::string kCpioMime("application/x-cpio");
245 const std::string kTarUrl("http://ignore.com/foo.tar");
246 const std::string kTargzUrl("http://ignore.com/foo.tar.gz");
247 const std::string kTgzUrl("http://ignore.com/foo.tgz");
248 const std::string kBadTgzUrl("http://ignore.com/foo.targz");
249 const std::string kUrl("http://ignore.com/foo");
251 // Firefox 3 does not decompress when we have unsupported mime types for
252 // certain filenames.
253 encoding_types.clear();
254 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
255 filter_context.SetDownload(false);
256 filter_context.SetMimeType(kTarMime);
257 filter_context.SetURL(GURL(kTargzUrl));
258 Filter::FixupEncodingTypes(filter_context, &encoding_types);
259 EXPECT_TRUE(encoding_types.empty());
261 encoding_types.clear();
262 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
263 filter_context.SetDownload(false);
264 filter_context.SetMimeType(kTarMime);
265 filter_context.SetURL(GURL(kTgzUrl));
266 Filter::FixupEncodingTypes(filter_context, &encoding_types);
267 EXPECT_TRUE(encoding_types.empty());
269 encoding_types.clear();
270 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
271 filter_context.SetDownload(false);
272 filter_context.SetMimeType(kCpioMime);
273 filter_context.SetURL(GURL(kTgzUrl));
274 Filter::FixupEncodingTypes(filter_context, &encoding_types);
275 EXPECT_TRUE(encoding_types.empty());
277 // Same behavior for downloads.
278 encoding_types.clear();
279 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
280 filter_context.SetDownload(true);
281 filter_context.SetMimeType(kCpioMime);
282 filter_context.SetURL(GURL(kTgzUrl));
283 Filter::FixupEncodingTypes(filter_context, &encoding_types);
284 EXPECT_TRUE(encoding_types.empty());
286 // Unsupported mime type with wrong file name, decompressed.
287 encoding_types.clear();
288 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
289 filter_context.SetDownload(false);
290 filter_context.SetMimeType(kTarMime);
291 filter_context.SetURL(GURL(kUrl));
292 Filter::FixupEncodingTypes(filter_context, &encoding_types);
293 ASSERT_EQ(1U, encoding_types.size());
294 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
296 encoding_types.clear();
297 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
298 filter_context.SetDownload(false);
299 filter_context.SetMimeType(kTarMime);
300 filter_context.SetURL(GURL(kTarUrl));
301 Filter::FixupEncodingTypes(filter_context, &encoding_types);
302 ASSERT_EQ(1U, encoding_types.size());
303 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
305 encoding_types.clear();
306 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
307 filter_context.SetDownload(false);
308 filter_context.SetMimeType(kTarMime);
309 filter_context.SetURL(GURL(kBadTgzUrl));
310 Filter::FixupEncodingTypes(filter_context, &encoding_types);
311 ASSERT_EQ(1U, encoding_types.size());
312 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
314 // Same behavior for downloads.
315 encoding_types.clear();
316 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
317 filter_context.SetDownload(true);
318 filter_context.SetMimeType(kTarMime);
319 filter_context.SetURL(GURL(kBadTgzUrl));
320 Filter::FixupEncodingTypes(filter_context, &encoding_types);
321 ASSERT_EQ(1U, encoding_types.size());
322 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
325 TEST(FilterTest, SupportedMimeGzip) {
326 // From issue 16430 - Files with supported mime types should be decompressed,
327 // even though these files end in .gz/.tgz.
328 MockFilterContext filter_context;
329 std::vector<Filter::FilterType> encoding_types;
330 const std::string kGzUrl("http://ignore.com/foo.gz");
331 const std::string kUrl("http://ignore.com/foo");
332 const std::string kHtmlMime("text/html");
333 const std::string kJavascriptMime("text/javascript");
335 // For files that does not end in .gz/.tgz, we always decompress.
336 encoding_types.clear();
337 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
338 filter_context.SetDownload(false);
339 filter_context.SetMimeType(kHtmlMime);
340 filter_context.SetURL(GURL(kUrl));
341 Filter::FixupEncodingTypes(filter_context, &encoding_types);
342 ASSERT_EQ(1U, encoding_types.size());
343 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
345 encoding_types.clear();
346 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
347 filter_context.SetDownload(true);
348 filter_context.SetMimeType(kHtmlMime);
349 filter_context.SetURL(GURL(kUrl));
350 Filter::FixupEncodingTypes(filter_context, &encoding_types);
351 ASSERT_EQ(1U, encoding_types.size());
352 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
354 // And also decompress files that end in .gz/.tgz.
355 encoding_types.clear();
356 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
357 filter_context.SetDownload(false);
358 filter_context.SetMimeType(kHtmlMime);
359 filter_context.SetURL(GURL(kGzUrl));
360 Filter::FixupEncodingTypes(filter_context, &encoding_types);
361 ASSERT_EQ(1U, encoding_types.size());
362 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
364 encoding_types.clear();
365 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
366 filter_context.SetDownload(false);
367 filter_context.SetMimeType(kJavascriptMime);
368 filter_context.SetURL(GURL(kGzUrl));
369 Filter::FixupEncodingTypes(filter_context, &encoding_types);
370 ASSERT_EQ(1U, encoding_types.size());
371 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
373 // Except on downloads, where they just get saved.
374 encoding_types.clear();
375 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
376 filter_context.SetDownload(true);
377 filter_context.SetMimeType(kHtmlMime);
378 filter_context.SetURL(GURL(kGzUrl));
379 Filter::FixupEncodingTypes(filter_context, &encoding_types);
380 EXPECT_TRUE(encoding_types.empty());
383 // Make sure a series of three pass-through filters copies the data cleanly.
384 // Regression test for http://crbug.com/418975.
385 TEST(FilterTest, ThreeFilterChain) {
386 scoped_ptr<PassThroughFilter> filter1(new PassThroughFilter);
387 scoped_ptr<PassThroughFilter> filter2(new PassThroughFilter);
388 scoped_ptr<PassThroughFilter> filter3(new PassThroughFilter);
390 filter1->InitBuffer(32 * 1024);
391 filter2->InitBuffer(32 * 1024);
392 filter3->InitBuffer(32 * 1024);
394 filter2->next_filter_ = filter3.Pass();
395 filter1->next_filter_ = filter2.Pass();
397 // Initialize the input array with a varying byte sequence.
398 const size_t input_array_size = 64 * 1024;
399 char input_array[input_array_size];
400 size_t read_array_index = 0;
401 for (size_t i = 0; i < input_array_size; i++) {
402 input_array[i] = i % 113;
405 const size_t output_array_size = 4 * 1024;
406 char output_array[output_array_size];
408 size_t compare_array_index = 0;
410 do {
411 // Read data from the filter chain.
412 int amount_read = output_array_size;
413 Filter::FilterStatus status = filter1->ReadData(output_array, &amount_read);
414 EXPECT_NE(Filter::FILTER_ERROR, status);
415 EXPECT_EQ(0, memcmp(output_array, input_array + compare_array_index,
416 amount_read));
417 compare_array_index += amount_read;
419 // Detect the various indications that data transfer along the chain is
420 // complete.
421 if (Filter::FILTER_DONE == status || Filter::FILTER_ERROR == status ||
422 (Filter::FILTER_OK == status && amount_read == 0) ||
423 (Filter::FILTER_NEED_MORE_DATA == status &&
424 read_array_index == input_array_size))
425 break;
427 if (Filter::FILTER_OK == status)
428 continue;
430 // Write needed data into the filter chain.
431 ASSERT_EQ(Filter::FILTER_NEED_MORE_DATA, status);
432 ASSERT_NE(0, filter1->stream_buffer_size());
433 size_t amount_to_copy = std::min(
434 static_cast<size_t>(filter1->stream_buffer_size()),
435 input_array_size - read_array_index);
436 memcpy(filter1->stream_buffer()->data(),
437 input_array + read_array_index,
438 amount_to_copy);
439 filter1->FlushStreamBuffer(amount_to_copy);
440 read_array_index += amount_to_copy;
441 } while (true);
443 EXPECT_EQ(read_array_index, input_array_size);
444 EXPECT_EQ(compare_array_index, input_array_size);
447 } // Namespace net