| OLD | NEW |
| (Empty) |
| 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/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" | |
| 9 | |
| 10 namespace net { | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 class PassThroughFilter : public Filter { | |
| 15 public: | |
| 16 PassThroughFilter() : Filter(FILTER_TYPE_UNSUPPORTED) {} | |
| 17 | |
| 18 FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) override { | |
| 19 return CopyOut(dest_buffer, dest_len); | |
| 20 } | |
| 21 | |
| 22 DISALLOW_COPY_AND_ASSIGN(PassThroughFilter); | |
| 23 }; | |
| 24 | |
| 25 } // namespace | |
| 26 | |
| 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")); | |
| 49 } | |
| 50 | |
| 51 // Check various fixups that modify content encoding lists. | |
| 52 TEST(FilterTest, ApacheGzip) { | |
| 53 MockFilterContext filter_context; | |
| 54 filter_context.SetSdchResponse(NULL); | |
| 55 | |
| 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; | |
| 61 | |
| 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()); | |
| 68 | |
| 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()); | |
| 74 | |
| 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()); | |
| 80 | |
| 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()); | |
| 88 | |
| 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()); | |
| 96 } | |
| 97 | |
| 98 TEST(FilterTest, GzipContentDispositionFilename) { | |
| 99 MockFilterContext filter_context; | |
| 100 filter_context.SetSdchResponse(NULL); | |
| 101 | |
| 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; | |
| 106 | |
| 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()); | |
| 113 } | |
| 114 | |
| 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()); | |
| 122 | |
| 123 std::vector<Filter::FilterType> encoding_types; | |
| 124 | |
| 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]); | |
| 134 | |
| 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]); | |
| 144 | |
| 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]); | |
| 152 } | |
| 153 | |
| 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()); | |
| 160 | |
| 161 std::vector<Filter::FilterType> encoding_types; | |
| 162 | |
| 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]); | |
| 170 | |
| 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]); | |
| 182 | |
| 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]); | |
| 190 } | |
| 191 | |
| 192 TEST(FilterTest, Svgz) { | |
| 193 MockFilterContext filter_context; | |
| 194 | |
| 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; | |
| 200 | |
| 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()); | |
| 210 | |
| 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()); | |
| 218 | |
| 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()); | |
| 228 | |
| 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()); | |
| 237 } | |
| 238 | |
| 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"); | |
| 250 | |
| 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()); | |
| 260 | |
| 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()); | |
| 268 | |
| 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()); | |
| 276 | |
| 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()); | |
| 285 | |
| 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()); | |
| 295 | |
| 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()); | |
| 304 | |
| 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()); | |
| 313 | |
| 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()); | |
| 323 } | |
| 324 | |
| 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"); | |
| 334 | |
| 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()); | |
| 344 | |
| 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()); | |
| 353 | |
| 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()); | |
| 363 | |
| 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()); | |
| 372 | |
| 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()); | |
| 381 } | |
| 382 | |
| 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); | |
| 389 | |
| 390 filter1->InitBuffer(32 * 1024); | |
| 391 filter2->InitBuffer(32 * 1024); | |
| 392 filter3->InitBuffer(32 * 1024); | |
| 393 | |
| 394 filter2->next_filter_ = filter3.Pass(); | |
| 395 filter1->next_filter_ = filter2.Pass(); | |
| 396 | |
| 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; | |
| 403 } | |
| 404 | |
| 405 const size_t output_array_size = 4 * 1024; | |
| 406 char output_array[output_array_size]; | |
| 407 | |
| 408 size_t compare_array_index = 0; | |
| 409 | |
| 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; | |
| 418 | |
| 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; | |
| 426 | |
| 427 if (Filter::FILTER_OK == status) | |
| 428 continue; | |
| 429 | |
| 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); | |
| 442 | |
| 443 EXPECT_EQ(read_array_index, input_array_size); | |
| 444 EXPECT_EQ(compare_array_index, input_array_size); | |
| 445 } | |
| 446 | |
| 447 } // Namespace net | |
| OLD | NEW |