Roll libvpx 861f35:1fff3e
[chromium-blink-merge.git] / net / filter / filter_unittest.cc
blobd0441fabb2cf70e5e3472b476f3da12b99d9adfd
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 TEST(FilterTest, SdchEncoding) {
52 // Handle content encodings including SDCH.
53 const std::string kTextHtmlMime("text/html");
54 MockFilterContext filter_context;
55 // Empty handle indicates to filter that SDCH is active.
56 filter_context.SetSdchResponse(
57 SdchManager::CreateEmptyDictionarySetForTesting().Pass());
59 std::vector<Filter::FilterType> encoding_types;
61 // Check for most common encoding, and verify it survives unchanged.
62 encoding_types.clear();
63 encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
64 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
65 filter_context.SetMimeType(kTextHtmlMime);
66 Filter::FixupEncodingTypes(filter_context, &encoding_types);
67 ASSERT_EQ(2U, encoding_types.size());
68 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
69 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
71 // Unchanged even with other mime types.
72 encoding_types.clear();
73 encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
74 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
75 filter_context.SetMimeType("other/type");
76 Filter::FixupEncodingTypes(filter_context, &encoding_types);
77 ASSERT_EQ(2U, encoding_types.size());
78 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
79 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
81 // Solo SDCH is extended to include optional gunzip.
82 encoding_types.clear();
83 encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
84 Filter::FixupEncodingTypes(filter_context, &encoding_types);
85 ASSERT_EQ(2U, encoding_types.size());
86 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
87 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
90 TEST(FilterTest, MissingSdchEncoding) {
91 // Handle interesting case where entire SDCH encoding assertion "got lost."
92 const std::string kTextHtmlMime("text/html");
93 MockFilterContext filter_context;
94 filter_context.SetSdchResponse(
95 SdchManager::CreateEmptyDictionarySetForTesting().Pass());
97 std::vector<Filter::FilterType> encoding_types;
99 // Loss of encoding, but it was an SDCH response with html type.
100 encoding_types.clear();
101 filter_context.SetMimeType(kTextHtmlMime);
102 Filter::FixupEncodingTypes(filter_context, &encoding_types);
103 ASSERT_EQ(2U, encoding_types.size());
104 EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
105 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
107 // Loss of encoding, but it was an SDCH response with a prefix that says it
108 // was an html type. Note that it *should* be the case that a precise match
109 // with "text/html" we be collected by GetMimeType() and passed in, but we
110 // coded the fixup defensively (scanning for a prefix of "text/html", so this
111 // is an example which could survive such confusion in the caller).
112 encoding_types.clear();
113 filter_context.SetMimeType("text/html; charset=UTF-8");
114 Filter::FixupEncodingTypes(filter_context, &encoding_types);
115 ASSERT_EQ(2U, encoding_types.size());
116 EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
117 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
119 // No encoding, but it was an SDCH response with non-html type.
120 encoding_types.clear();
121 filter_context.SetMimeType("other/mime");
122 Filter::FixupEncodingTypes(filter_context, &encoding_types);
123 ASSERT_EQ(2U, encoding_types.size());
124 EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
125 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
128 // FixupEncodingTypes() should leave gzip encoding intact.
129 TEST(FilterTest, Gzip) {
130 const std::string kUrl("http://example.com/foo");
131 MockFilterContext filter_context;
132 std::vector<Filter::FilterType> encoding_types;
133 filter_context.SetURL(GURL(kUrl));
135 Filter::FixupEncodingTypes(filter_context, &encoding_types);
136 EXPECT_EQ(0U, encoding_types.size());
138 encoding_types.clear();
139 encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
140 Filter::FixupEncodingTypes(filter_context, &encoding_types);
141 ASSERT_EQ(1U, encoding_types.size());
142 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
145 // Make sure a series of three pass-through filters copies the data cleanly.
146 // Regression test for http://crbug.com/418975.
147 TEST(FilterTest, ThreeFilterChain) {
148 scoped_ptr<PassThroughFilter> filter1(new PassThroughFilter);
149 scoped_ptr<PassThroughFilter> filter2(new PassThroughFilter);
150 scoped_ptr<PassThroughFilter> filter3(new PassThroughFilter);
152 filter1->InitBuffer(32 * 1024);
153 filter2->InitBuffer(32 * 1024);
154 filter3->InitBuffer(32 * 1024);
156 filter2->next_filter_ = filter3.Pass();
157 filter1->next_filter_ = filter2.Pass();
159 // Initialize the input array with a varying byte sequence.
160 const size_t input_array_size = 64 * 1024;
161 char input_array[input_array_size];
162 size_t read_array_index = 0;
163 for (size_t i = 0; i < input_array_size; i++) {
164 input_array[i] = i % 113;
167 const size_t output_array_size = 4 * 1024;
168 char output_array[output_array_size];
170 size_t compare_array_index = 0;
172 do {
173 // Read data from the filter chain.
174 int amount_read = output_array_size;
175 Filter::FilterStatus status = filter1->ReadData(output_array, &amount_read);
176 EXPECT_NE(Filter::FILTER_ERROR, status);
177 EXPECT_EQ(0, memcmp(output_array, input_array + compare_array_index,
178 amount_read));
179 compare_array_index += amount_read;
181 // Detect the various indications that data transfer along the chain is
182 // complete.
183 if (Filter::FILTER_DONE == status || Filter::FILTER_ERROR == status ||
184 (Filter::FILTER_OK == status && amount_read == 0) ||
185 (Filter::FILTER_NEED_MORE_DATA == status &&
186 read_array_index == input_array_size))
187 break;
189 if (Filter::FILTER_OK == status)
190 continue;
192 // Write needed data into the filter chain.
193 ASSERT_EQ(Filter::FILTER_NEED_MORE_DATA, status);
194 ASSERT_NE(0, filter1->stream_buffer_size());
195 size_t amount_to_copy = std::min(
196 static_cast<size_t>(filter1->stream_buffer_size()),
197 input_array_size - read_array_index);
198 memcpy(filter1->stream_buffer()->data(),
199 input_array + read_array_index,
200 amount_to_copy);
201 filter1->FlushStreamBuffer(amount_to_copy);
202 read_array_index += amount_to_copy;
203 } while (true);
205 EXPECT_EQ(read_array_index, input_array_size);
206 EXPECT_EQ(compare_array_index, input_array_size);
209 } // Namespace net