15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/filter/mock_filter_context.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/filter/sdch_filter.h" 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/url_request/url_request_context.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_http_job.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/zlib/zlib.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Provide sample data and compression results with a sample VCDIFF dictionary. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note an SDCH dictionary has extra meta-data before the VCDIFF dictionary. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kTestVcdiffDictionary[] = "DictionaryFor" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SdchCompression1SdchCompression2SdchCompression3SdchCompression\n"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pre-compression test data. Note that we pad with a lot of highly gzip 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// compressible content to help to exercise the chaining pipeline. That is why 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// there are a PILE of zeros at the start and end. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This will ensure that gzip compressed data can be fed to the chain in one 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gulp, but (with careful selection of intermediate buffers) that it takes 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// several sdch buffers worth of data to satisfy the sdch filter. See detailed 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CHECK() calls in FilterChaining test for specifics. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kTestData[] = "0000000000000000000000000000000000000000000000" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0000000000000000000000000000TestData " 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SdchCompression1SdchCompression2SdchCompression3SdchCompression" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "00000000000000000000000000000000000000000000000000000000000000000000000000" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "000000000000000000000000000000000000000\n"; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note SDCH compressed data will include a reference to the SDCH dictionary. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kSdchCompressedTestData[] = 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\326\303\304\0\0\001M\0\201S\202\004\0\201E\006\001" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "00000000000000000000000000000000000000000000000000000000000000000000000000" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "TestData 00000000000000000000000000000000000000000000000000000000000000000" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "000000000000000000000000000000000000000000000000\n\001S\023\077\001r\r"; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SdchFilterTest : public testing::Test { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SdchFilterTest() 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : test_vcdiff_dictionary_(kTestVcdiffDictionary, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(kTestVcdiffDictionary) - 1), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vcdiff_compressed_data_(kSdchCompressedTestData, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(kSdchCompressedTestData) - 1), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expanded_(kTestData, sizeof(kTestData) - 1), 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sdch_manager_(new SdchManager), 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context_(new MockFilterContext) { 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) URLRequestContext* url_request_context = 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context_->GetModifiableURLRequestContext(); 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) url_request_context->set_sdch_manager(sdch_manager_.get()); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Attempt to add a dictionary to the manager; returns whether or not 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the attempt succeeded. 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool AddSdchDictionary(const std::string& dictionary_text, 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& gurl) { 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string list; 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sdch_manager_->GetAvailDictionaryList(gurl, &list); 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sdch_manager_->AddSdchDictionary(dictionary_text, gurl); 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string list2; 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sdch_manager_->GetAvailDictionaryList(gurl, &list2); 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The list of hashes should change iff the addition succeeds. 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (list != list2); 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MockFilterContext* filter_context() { return filter_context_.get(); } 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string NewSdchCompressedData(const std::string dictionary) { 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string client_hash; 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string server_hash; 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SdchManager::GenerateHash(dictionary, &client_hash, &server_hash); 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Build compressed data that refers to our dictionary. 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string compressed(server_hash); 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci compressed.append("\0", 1); 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci compressed.append(vcdiff_compressed_data_); 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return compressed; 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string test_vcdiff_dictionary_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string vcdiff_compressed_data_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string expanded_; // Desired final, decompressed data. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SdchManager> sdch_manager_; 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<MockFilterContext> filter_context_; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, Hashing) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string client_hash, server_hash; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary("test contents"); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SdchManager::GenerateHash(dictionary, &client_hash, &server_hash); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(client_hash, "lMQBjS3P"); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(server_hash, "MyciMVll"); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Provide a generic helper function for trying to filter data. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function repeatedly calls the filter to process data, until the entire 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// source is consumed. The return value from the filter is appended to output. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This allows us to vary input and output block sizes in order to test for edge 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// effects (boundary effects?) during the filtering process. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function provides data to the filter in blocks of no-more-than the 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specified input_block_length. It allows the filter to fill no more than 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// output_buffer_length in any one call to proccess (a.k.a., Read) data, and 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// concatenates all these little output blocks into the singular output string. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool FilterTestData(const std::string& source, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t input_block_length, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t output_buffer_length, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Filter* filter, std::string* output) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(input_block_length, 0u); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Filter::FilterStatus status(Filter::FILTER_NEED_MORE_DATA); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t source_index = 0; 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<char[]> output_buffer(new char[output_buffer_length]); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t input_amount = std::min(input_block_length, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<size_t>(filter->stream_buffer_size())); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int copy_amount = std::min(input_amount, source.size() - source_index); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (copy_amount > 0 && status == Filter::FILTER_NEED_MORE_DATA) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(filter->stream_buffer()->data(), source.data() + source_index, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copy_amount); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->FlushStreamBuffer(copy_amount); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_index += copy_amount; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_length = output_buffer_length; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = filter->ReadData(output_buffer.get(), &buffer_length); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->append(output_buffer.get(), buffer_length); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status == Filter::FILTER_ERROR) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callers assume that FILTER_OK with no output buffer means FILTER_DONE. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Filter::FILTER_OK == status && 0 == buffer_length) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (copy_amount == 0 && buffer_length == 0) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (1); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static std::string NewSdchDictionary(const std::string& domain) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!domain.empty()) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary.append("Domain: "); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary.append(domain); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary.append("\n"); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary.append("\n"); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary.append(kTestVcdiffDictionary, sizeof(kTestVcdiffDictionary) - 1); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dictionary; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, EmptyInputOk) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char output_buffer[20]; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string("http://ignore.com"); 176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string)); 177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // With no input data, try to read output. 18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int output_bytes_or_buffer_size = sizeof(output_buffer); 18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Filter::FilterStatus status = filter->ReadData(output_buffer, 18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &output_bytes_or_buffer_size); 18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(0, output_bytes_or_buffer_size); 18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, status); 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Make sure that the filter context has everything that might be 18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// nuked from it during URLRequest teardown before the SdchFilter 19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// destructor. 19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(SdchFilterTest, SparseContextOk) { 19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) char output_buffer[20]; 19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string url_string("http://ignore.com"); 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) filter_context()->SetURL(GURL(url_string)); 19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With no input data, try to read output. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int output_bytes_or_buffer_size = sizeof(output_buffer); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Filter::FilterStatus status = filter->ReadData(output_buffer, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &output_bytes_or_buffer_size); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, output_bytes_or_buffer_size); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, status); 20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Partially tear down context. Anything that goes through request() 20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // without checking it for null in the URLRequestJob::HttpFilterContext 20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // implementation is suspect. Everything that does check it for null should 21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // return null. This is to test for incorrectly relying on filter_context() 21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // from the SdchFilter destructor. 21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) filter_context()->NukeUnstableInterfaces(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, PassThroughWhenTentative) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Selective a tentative filter (which can fall back to pass through). 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_GZIP_HELPING_SDCH); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char output_buffer[20]; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Response code needs to be 200 to allow a pass through. 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetResponseCode(200); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string("http://ignore.com"); 223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string)); 224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Supply enough data to force a pass-through mode.. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string non_gzip_content("not GZIPed data"); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* input_buffer = filter->stream_buffer()->data(); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int input_buffer_size = filter->stream_buffer_size(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(static_cast<int>(non_gzip_content.size()), 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_buffer_size); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(input_buffer, non_gzip_content.data(), 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_gzip_content.size()); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->FlushStreamBuffer(non_gzip_content.size()); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to read output. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int output_bytes_or_buffer_size = sizeof(output_buffer); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Filter::FilterStatus status = filter->ReadData(output_buffer, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &output_bytes_or_buffer_size); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(non_gzip_content.size(), 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<size_t>(output_bytes_or_buffer_size)); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(sizeof(output_buffer), 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<size_t>(output_bytes_or_buffer_size)); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_buffer[output_bytes_or_buffer_size] = '\0'; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(non_gzip_content == output_buffer); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, status); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, RefreshBadReturnCode) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Selective a tentative filter (which can fall back to pass through). 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH_POSSIBLE); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char output_buffer[20]; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Response code needs to be 200 to allow a pass through. 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetResponseCode(403); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Meta refresh will only appear for html content 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetMimeType("text/html"); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string("http://ignore.com"); 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string)); 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Supply enough data to force a pass-through mode, which means we have 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provided more than 9 characters that can't be a dictionary hash. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string non_sdch_content("This is not SDCH"); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* input_buffer = filter->stream_buffer()->data(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int input_buffer_size = filter->stream_buffer_size(); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(static_cast<int>(non_sdch_content.size()), 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_buffer_size); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(input_buffer, non_sdch_content.data(), 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_sdch_content.size()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->FlushStreamBuffer(non_sdch_content.size()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to read output. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int output_bytes_or_buffer_size = sizeof(output_buffer); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Filter::FilterStatus status = filter->ReadData(output_buffer, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &output_bytes_or_buffer_size); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have read a long and complicated meta-refresh request. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(sizeof(output_buffer) == output_bytes_or_buffer_size); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check at least the prefix of the return. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, strncmp(output_buffer, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<head><META HTTP-EQUIV=\"Refresh\" CONTENT=\"0\"></head>", 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(output_buffer))); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_OK, status); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, ErrorOnBadReturnCode) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Selective a tentative filter (which can fall back to pass through). 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH_POSSIBLE); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char output_buffer[20]; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Response code needs to be 200 to allow a pass through. 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetResponseCode(403); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Meta refresh will only appear for html content, so set to something else 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to induce an error (we can't meta refresh). 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetMimeType("anything"); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string("http://ignore.com"); 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string)); 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Supply enough data to force a pass-through mode, which means we have 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provided more than 9 characters that can't be a dictionary hash. 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string non_sdch_content("This is not SDCH"); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* input_buffer = filter->stream_buffer()->data(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int input_buffer_size = filter->stream_buffer_size(); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(static_cast<int>(non_sdch_content.size()), 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_buffer_size); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(input_buffer, non_sdch_content.data(), 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_sdch_content.size()); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->FlushStreamBuffer(non_sdch_content.size()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to read output. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int output_bytes_or_buffer_size = sizeof(output_buffer); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Filter::FilterStatus status = filter->ReadData(output_buffer, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &output_bytes_or_buffer_size); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, output_bytes_or_buffer_size); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_ERROR, status); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, ErrorOnBadReturnCodeWithHtml) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Selective a tentative filter (which can fall back to pass through). 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH_POSSIBLE); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char output_buffer[20]; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Response code needs to be 200 to allow a pass through. 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetResponseCode(403); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Meta refresh will only appear for html content 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetMimeType("text/html"); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string("http://ignore.com"); 338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string)); 339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Supply enough data to force a pass-through mode, which means we have 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provided more than 9 characters that can't be a dictionary hash. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string non_sdch_content("This is not SDCH"); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* input_buffer = filter->stream_buffer()->data(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int input_buffer_size = filter->stream_buffer_size(); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(static_cast<int>(non_sdch_content.size()), 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_buffer_size); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(input_buffer, non_sdch_content.data(), 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_sdch_content.size()); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->FlushStreamBuffer(non_sdch_content.size()); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to read output. 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int output_bytes_or_buffer_size = sizeof(output_buffer); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Filter::FilterStatus status = filter->ReadData(output_buffer, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &output_bytes_or_buffer_size); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have read a long and complicated meta-refresh request. 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(sizeof(output_buffer), 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<size_t>(output_bytes_or_buffer_size)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check at least the prefix of the return. 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, strncmp(output_buffer, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<head><META HTTP-EQUIV=\"Refresh\" CONTENT=\"0\"></head>", 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(output_buffer))); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_OK, status); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, BasicBadDictionary) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char output_buffer[20]; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string("http://ignore.com"); 374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string)); 375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Supply bogus data (which doesn't yet specify a full dictionary hash). 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Dictionary hash is 8 characters followed by a null. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary_hash_prefix("123"); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* input_buffer = filter->stream_buffer()->data(); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int input_buffer_size = filter->stream_buffer_size(); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(static_cast<int>(dictionary_hash_prefix.size()), 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_buffer_size); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(input_buffer, dictionary_hash_prefix.data(), 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary_hash_prefix.size()); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->FlushStreamBuffer(dictionary_hash_prefix.size()); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With less than a dictionary specifier, try to read output. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int output_bytes_or_buffer_size = sizeof(output_buffer); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Filter::FilterStatus status = filter->ReadData(output_buffer, 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &output_bytes_or_buffer_size); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, output_bytes_or_buffer_size); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, status); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Provide enough data to complete *a* hash, but it is bogus, and not in our 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list of dictionaries, so the filter should error out immediately. 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary_hash_postfix("4abcd\0", 6); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_LT(dictionary_hash_postfix.size(), 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<size_t>(input_buffer_size)); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(input_buffer, dictionary_hash_postfix.data(), 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary_hash_postfix.size()); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->FlushStreamBuffer(dictionary_hash_postfix.size()); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With a non-existant dictionary specifier, try to read output. 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_bytes_or_buffer_size = sizeof(output_buffer); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = filter->ReadData(output_buffer, &output_bytes_or_buffer_size); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, output_bytes_or_buffer_size); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_ERROR, status); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(sdch_manager_->IsInSupportedDomain(GURL(url_string))); 416f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sdch_manager_->ClearBlacklistings(); 417f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(GURL(url_string))); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, DictionaryAddOnce) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check we can't add it twice. 4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(AddSdchDictionary(dictionary, url)); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain2 = "sdchtest2.com"; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Don't test adding a second dictionary if our limits are tight. 4356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (SdchManager::kMaxDictionaryCount > 1) { 4366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Construct a second SDCH dictionary from a VCDIFF dictionary. 4376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) std::string dictionary2(NewSdchDictionary(kSampleDomain2)); 4386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 4396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) std::string url_string2 = "http://" + kSampleDomain2; 4406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) GURL url2(url_string2); 4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary2, url2)); 4426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, BasicDictionary) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed(NewSdchCompressedData(dictionary)); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(url); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 462f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t feed_block_size = 100; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t output_block_size = 100; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(compressed, feed_block_size, output_block_size, 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.get(), &output)); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decode with really small buffers (size 1) to check for edge effects. 472f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter.reset(Filter::Factory(filter_types, *filter_context())); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = 1; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = 1; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(compressed, feed_block_size, output_block_size, 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.get(), &output)); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, NoDecodeHttps) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed(NewSdchCompressedData(dictionary)); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 497f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL("https://" + kSampleDomain)); 498f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t feed_block_size(100); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t output_block_size(100); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FilterTestData(compressed, feed_block_size, output_block_size, 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.get(), &output)); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Current failsafe TODO/hack refuses to decode any content that doesn't use 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http as the scheme (see use of DICTIONARY_SELECTED_FOR_NON_HTTP). 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following tests this blockage. Note that blacklisting results, so we 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we need separate tests for each of these. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, NoDecodeFtp) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed(NewSdchCompressedData(dictionary)); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 527f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL("ftp://" + kSampleDomain)); 528f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t feed_block_size(100); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t output_block_size(100); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FilterTestData(compressed, feed_block_size, output_block_size, 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.get(), &output)); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, NoDecodeFileColon) { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 5461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed(NewSdchCompressedData(dictionary)); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 553f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL("file://" + kSampleDomain)); 554f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t feed_block_size(100); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t output_block_size(100); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FilterTestData(compressed, feed_block_size, output_block_size, 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.get(), &output)); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, NoDecodeAboutColon) { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed(NewSdchCompressedData(dictionary)); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 579f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL("about://" + kSampleDomain)); 580f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t feed_block_size(100); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t output_block_size(100); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FilterTestData(compressed, feed_block_size, output_block_size, 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.get(), &output)); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, NoDecodeJavaScript) { 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed(NewSdchCompressedData(dictionary)); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL("javascript://" + kSampleDomain)); 606f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t feed_block_size(100); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t output_block_size(100); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FilterTestData(compressed, feed_block_size, output_block_size, 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.get(), &output)); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, CanStillDecodeHttp) { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed(NewSdchCompressedData(dictionary)); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 631f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL("http://" + kSampleDomain)); 632f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t feed_block_size(100); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t output_block_size(100); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(compressed, feed_block_size, output_block_size, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.get(), &output)); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, CrossDomainDictionaryUse) { 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed(NewSdchCompressedData(dictionary)); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decode with content arriving from the "wrong" domain. 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This tests SdchManager::CanSet(). 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL wrong_domain_url("http://www.wrongdomain.com"); 660f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(wrong_domain_url); 661f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t feed_block_size = 100; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t output_block_size = 100; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FilterTestData(compressed, feed_block_size, output_block_size, 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.get(), &output)); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output.size(), 0u); // No output written. 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 670f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(GURL(url_string))); 671f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(sdch_manager_->IsInSupportedDomain(wrong_domain_url)); 672f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sdch_manager_->ClearBlacklistings(); 673f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(wrong_domain_url)); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, DictionaryPathValidation) { 6776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Can't test path distinction between dictionaries if we aren't allowed 6786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // more than one dictionary. 6796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (SdchManager::kMaxDictionaryCount <= 1) 6806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 6816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 6891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a dictionary with a path restriction, by prefixing dictionary. 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string path("/special_path/bin"); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary_with_path("Path: " + path + "\n"); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary_with_path.append(dictionary); 6951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL url2(url_string + path); 6961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary_with_path, url2)); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed_for_path(NewSdchCompressedData(dictionary_with_path)); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test decode the path data, arriving from a valid path. 704f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string + path)); 705f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t feed_block_size = 100; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t output_block_size = 100; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(compressed_for_path, feed_block_size, 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test decode the path data, arriving from a invalid path. 716f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string)); 717f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter.reset(Filter::Factory(filter_types, *filter_context())); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = 100; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = 100; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FilterTestData(compressed_for_path, feed_block_size, 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output.size(), 0u); // No output written. 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 726f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(sdch_manager_->IsInSupportedDomain(GURL(url_string))); 727f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sdch_manager_->ClearBlacklistings(); 728f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(GURL(url_string))); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, DictionaryPortValidation) { 7326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Can't test port distinction between dictionaries if we aren't allowed 7336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // more than one dictionary. 7346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (SdchManager::kMaxDictionaryCount <= 1) 7356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 7366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 7441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a dictionary with a port restriction, by prefixing old dictionary. 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string port("502"); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary_with_port("Port: " + port + "\n"); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary_with_port.append("Port: 80\n"); // Add default port. 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary_with_port.append(dictionary); 7511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary_with_port, 7521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL(url_string + ":" + port))); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed_for_port(NewSdchCompressedData(dictionary_with_port)); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test decode the port data, arriving from a valid port. 760f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string + ":" + port)); 761f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t feed_block_size = 100; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t output_block_size = 100; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(compressed_for_port, feed_block_size, 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test decode the port data, arriving from a valid (default) port. 771f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string)); // Default port. 772f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter.reset(Filter::Factory(filter_types, *filter_context())); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = 100; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = 100; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(compressed_for_port, feed_block_size, 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test decode the port data, arriving from a invalid port. 782f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(GURL(url_string + ":" + port + "1")); 783f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter.reset(Filter::Factory(filter_types, *filter_context())); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = 100; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = 100; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FilterTestData(compressed_for_port, feed_block_size, 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output.size(), 0u); // No output written. 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 792f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(sdch_manager_->IsInSupportedDomain(GURL(url_string))); 793f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sdch_manager_->ClearBlacklistings(); 794f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(GURL(url_string))); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper function to perform gzip compression of data. 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static std::string gzip_compress(const std::string &input) { 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z_stream zlib_stream; 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&zlib_stream, 0, sizeof(zlib_stream)); 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int code; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize zlib 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) code = deflateInit2(&zlib_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -MAX_WBITS, 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8, // DEF_MEM_LEVEL 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Z_DEFAULT_STRATEGY); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(Z_OK, code); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill in zlib control block 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zlib_stream.next_in = bit_cast<Bytef*>(input.data()); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zlib_stream.avail_in = input.size(); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assume we can compress into similar buffer (add 100 bytes to be sure). 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t gzip_compressed_length = zlib_stream.avail_in + 100; 819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<char[]> gzip_compressed(new char[gzip_compressed_length]); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zlib_stream.next_out = bit_cast<Bytef*>(gzip_compressed.get()); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zlib_stream.avail_out = gzip_compressed_length; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The GZIP header (see RFC 1952): 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // +---+---+---+---+---+---+---+---+---+---+ 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |ID1|ID2|CM |FLG| MTIME |XFL|OS | 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // +---+---+---+---+---+---+---+---+---+---+ 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ID1 \037 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ID2 \213 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CM \010 (compression method == DEFLATE) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FLG \000 (special flags that we do not support) 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MTIME Unix format modification time (0 means not available) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // XFL 2-4? DEFLATE flags 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OS ???? Operating system indicator (255 means unknown) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Header value we generate: 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kGZipHeader[] = { '\037', '\213', '\010', '\000', '\000', 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '\000', '\000', '\000', '\002', '\377' }; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(zlib_stream.avail_out, sizeof(kGZipHeader)); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(zlib_stream.next_out, kGZipHeader, sizeof(kGZipHeader)); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zlib_stream.next_out += sizeof(kGZipHeader); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zlib_stream.avail_out -= sizeof(kGZipHeader); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do deflate 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) code = deflate(&zlib_stream, Z_FINISH); 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gzip_compressed_length -= zlib_stream.avail_out; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string compressed(gzip_compressed.get(), gzip_compressed_length); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deflateEnd(&zlib_stream); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return compressed; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SdchFilterChainingTest { 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static Filter* Factory(const std::vector<Filter::FilterType>& types, 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FilterContext& context, int size) { 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Filter::FactoryForTests(types, context, size); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that filters can be cascaded (chained) so that the output of one filter 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is processed by the next one. This is most critical for SDCH, which is 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// routinely followed by gzip (during encoding). The filter we'll test for will 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// do the gzip decoding first, and then decode the SDCH content. 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, FilterChaining) { 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 8731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sdch_compressed(NewSdchCompressedData(dictionary)); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use Gzip to compress the sdch sdch_compressed data. 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string gzip_compressed_sdch = gzip_compress(sdch_compressed); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a chained filter. 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_GZIP); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First try with a large buffer (larger than test input, or compressed data). 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kLargeInputBufferSize(1000); // Used internally in filters. 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(kLargeInputBufferSize, gzip_compressed_sdch.size()); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(kLargeInputBufferSize, sdch_compressed.size()); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(kLargeInputBufferSize, expanded_.size()); 890f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(url); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Filter> filter( 892f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SdchFilterChainingTest::Factory(filter_types, *filter_context(), 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLargeInputBufferSize)); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(static_cast<int>(kLargeInputBufferSize), 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->stream_buffer_size()); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that chained filter is waiting for data. 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char tiny_output_buffer[10]; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tiny_output_size = sizeof(tiny_output_buffer); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->ReadData(tiny_output_buffer, &tiny_output_size)); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make chain process all data. 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t feed_block_size = kLargeInputBufferSize; 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t output_block_size = kLargeInputBufferSize; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(gzip_compressed_sdch, feed_block_size, 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next try with a mid-sized internal buffer size. 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kMidSizedInputBufferSize(100); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Buffer should be big enough to swallow whole gzip content. 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(kMidSizedInputBufferSize, gzip_compressed_sdch.size()); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Buffer should be small enough that entire SDCH content can't fit. 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll go even further, and force the chain to flush the buffer between the 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // two filters more than once (that is why we multiply by 2). 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_LT(kMidSizedInputBufferSize * 2, sdch_compressed.size()); 919f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(url); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.reset( 921f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SdchFilterChainingTest::Factory(filter_types, *filter_context(), 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMidSizedInputBufferSize)); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(static_cast<int>(kMidSizedInputBufferSize), 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->stream_buffer_size()); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = kMidSizedInputBufferSize; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = kMidSizedInputBufferSize; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(gzip_compressed_sdch, feed_block_size, 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next try with a tiny input and output buffer to cover edge effects. 934f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter.reset(SdchFilterChainingTest::Factory(filter_types, *filter_context(), 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLargeInputBufferSize)); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(static_cast<int>(kLargeInputBufferSize), 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->stream_buffer_size()); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = 1; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = 1; 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(gzip_compressed_sdch, feed_block_size, 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, DefaultGzipIfSdch) { 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 9551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sdch_compressed(NewSdchCompressedData(dictionary)); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use Gzip to compress the sdch sdch_compressed data. 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string gzip_compressed_sdch = gzip_compress(sdch_compressed); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only claim to have sdch content, but really use the gzipped sdch content. 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // System should automatically add the missing (optional) gzip. 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_SDCH); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 967f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetMimeType("anything/mime"); 968f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetSdchResponse(true); 969f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Filter::FixupEncodingTypes(*filter_context(), &filter_types); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(filter_types.size(), 2u); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[1], Filter::FILTER_TYPE_GZIP_HELPING_SDCH); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First try with a large buffer (larger than test input, or compressed data). 975f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(url); 976f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that chained filter is waiting for data. 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char tiny_output_buffer[10]; 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tiny_output_size = sizeof(tiny_output_buffer); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->ReadData(tiny_output_buffer, &tiny_output_size)); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t feed_block_size = 100; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t output_block_size = 100; 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(gzip_compressed_sdch, feed_block_size, 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next try with a tiny buffer to cover edge effects. 993f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter.reset(Filter::Factory(filter_types, *filter_context())); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = 1; 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = 1; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(gzip_compressed_sdch, feed_block_size, 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, AcceptGzipSdchIfGzip) { 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 10111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sdch_compressed(NewSdchCompressedData(dictionary)); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use Gzip to compress the sdch sdch_compressed data. 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string gzip_compressed_sdch = gzip_compress(sdch_compressed); 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some proxies strip the content encoding statement down to a mere gzip, but 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pass through the original content (with full sdch,gzip encoding). 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only claim to have gzip content, but really use the gzipped sdch content. 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // System should automatically add the missing (optional) sdch. 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_GZIP); 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetMimeType("anything/mime"); 1026f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetSdchResponse(true); 1027f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Filter::FixupEncodingTypes(*filter_context(), &filter_types); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(filter_types.size(), 3u); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH_POSSIBLE); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[1], Filter::FILTER_TYPE_GZIP_HELPING_SDCH); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[2], Filter::FILTER_TYPE_GZIP); 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First try with a large buffer (larger than test input, or compressed data). 1034f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(url); 1035f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that chained filter is waiting for data. 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char tiny_output_buffer[10]; 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tiny_output_size = sizeof(tiny_output_buffer); 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->ReadData(tiny_output_buffer, &tiny_output_size)); 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t feed_block_size = 100; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t output_block_size = 100; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(gzip_compressed_sdch, feed_block_size, 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next try with a tiny buffer to cover edge effects. 1052f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter.reset(Filter::Factory(filter_types, *filter_context())); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = 1; 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = 1; 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(gzip_compressed_sdch, feed_block_size, 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, DefaultSdchGzipIfEmpty) { 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 10701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sdch_compressed(NewSdchCompressedData(dictionary)); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use Gzip to compress the sdch sdch_compressed data. 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string gzip_compressed_sdch = gzip_compress(sdch_compressed); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only claim to have non-encoded content, but really use the gzipped sdch 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content. 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // System should automatically add the missing (optional) sdch,gzip. 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1082f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetMimeType("anything/mime"); 1083f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetSdchResponse(true); 1084f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Filter::FixupEncodingTypes(*filter_context(), &filter_types); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(filter_types.size(), 2u); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH_POSSIBLE); 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[1], Filter::FILTER_TYPE_GZIP_HELPING_SDCH); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First try with a large buffer (larger than test input, or compressed data). 1090f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(url); 1091f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that chained filter is waiting for data. 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char tiny_output_buffer[10]; 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tiny_output_size = sizeof(tiny_output_buffer); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->ReadData(tiny_output_buffer, &tiny_output_size)); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t feed_block_size = 100; 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t output_block_size = 100; 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(gzip_compressed_sdch, feed_block_size, 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next try with a tiny buffer to cover edge effects. 1108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter.reset(Filter::Factory(filter_types, *filter_context())); 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = 1; 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = 1; 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(gzip_compressed_sdch, feed_block_size, 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SdchFilterTest, AcceptGzipGzipSdchIfGzip) { 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a valid SDCH dictionary from a VCDIFF dictionary. 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSampleDomain = "sdchtest.com"; 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dictionary(NewSdchDictionary(kSampleDomain)); 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string = "http://" + kSampleDomain; 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 11261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(AddSdchDictionary(dictionary, url)); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sdch_compressed(NewSdchCompressedData(dictionary)); 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vodaphone (UK) Mobile Broadband provides double gzipped sdch with a content 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // encoding of merely gzip (apparently, only listing the extra level of 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wrapper compression they added, but discarding the actual content encoding. 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use Gzip to double compress the sdch sdch_compressed data. 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string double_gzip_compressed_sdch = gzip_compress(gzip_compress( 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_compressed)); 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only claim to have gzip content, but really use the double gzipped sdch 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content. 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // System should automatically add the missing (optional) sdch, gzip decoders. 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> filter_types; 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_types.push_back(Filter::FILTER_TYPE_GZIP); 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetMimeType("anything/mime"); 1144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetSdchResponse(true); 1145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Filter::FixupEncodingTypes(*filter_context(), &filter_types); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(filter_types.size(), 3u); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH_POSSIBLE); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[1], Filter::FILTER_TYPE_GZIP_HELPING_SDCH); 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(filter_types[2], Filter::FILTER_TYPE_GZIP); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First try with a large buffer (larger than test input, or compressed data). 1152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter_context()->SetURL(url); 1153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context())); 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that chained filter is waiting for data. 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char tiny_output_buffer[10]; 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tiny_output_size = sizeof(tiny_output_buffer); 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter->ReadData(tiny_output_buffer, &tiny_output_size)); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t feed_block_size = 100; 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t output_block_size = 100; 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(double_gzip_compressed_sdch, feed_block_size, 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next try with a tiny buffer to cover edge effects. 1169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) filter.reset(Filter::Factory(filter_types, *filter_context())); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feed_block_size = 1; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size = 1; 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.clear(); 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FilterTestData(double_gzip_compressed_sdch, feed_block_size, 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_block_size, filter.get(), &output)); 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output, expanded_); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1180