| Index: net/filter/sdch_filter_unittest.cc
|
| diff --git a/net/filter/sdch_filter_unittest.cc b/net/filter/sdch_filter_unittest.cc
|
| index 79b567369d2d7dafb4e34e10b5c81a9b706eb1c6..5866372f3b74ddba1cae529e46833b6caca08f81 100644
|
| --- a/net/filter/sdch_filter_unittest.cc
|
| +++ b/net/filter/sdch_filter_unittest.cc
|
| @@ -10,6 +10,7 @@
|
|
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/test/simple_test_clock.h"
|
| #include "net/base/io_buffer.h"
|
| #include "net/filter/mock_filter_context.h"
|
| #include "net/filter/sdch_filter.h"
|
| @@ -63,8 +64,8 @@ class SdchFilterTest : public testing::Test {
|
| url_request_context->set_sdch_manager(sdch_manager_.get());
|
| }
|
|
|
| - // Attempt to add a dictionary to the manager; returns whether or not
|
| - // the attempt succeeded.
|
| + // Attempt to add a dictionary to the manager and probe for success or
|
| + // failure.
|
| bool AddSdchDictionary(const std::string& dictionary_text,
|
| const GURL& gurl) {
|
| return sdch_manager_->AddSdchDictionary(dictionary_text, gurl) == SDCH_OK;
|
| @@ -72,6 +73,13 @@ class SdchFilterTest : public testing::Test {
|
|
|
| MockFilterContext* filter_context() { return filter_context_.get(); }
|
|
|
| + // Sets both the GURL and the SDCH response for a filter context.
|
| + void SetupFilterContextWithGURL(GURL url) {
|
| + filter_context_->SetURL(url);
|
| + filter_context_->SetSdchResponse(
|
| + sdch_manager_->GetDictionarySet(url).Pass());
|
| + }
|
| +
|
| std::string NewSdchCompressedData(const std::string dictionary) {
|
| std::string client_hash;
|
| std::string server_hash;
|
| @@ -159,6 +167,19 @@ static std::string NewSdchDictionary(const std::string& domain) {
|
| return dictionary;
|
| }
|
|
|
| +static std::string NewSdchExpiredDictionary(const std::string& domain) {
|
| + std::string dictionary;
|
| + if (!domain.empty()) {
|
| + dictionary.append("Domain: ");
|
| + dictionary.append(domain);
|
| + dictionary.append("\n");
|
| + }
|
| + dictionary.append("Max-Age: 0\n");
|
| + dictionary.append("\n");
|
| + dictionary.append(kTestVcdiffDictionary, sizeof(kTestVcdiffDictionary) - 1);
|
| + return dictionary;
|
| +}
|
| +
|
| //------------------------------------------------------------------------------
|
|
|
| TEST_F(SdchFilterTest, EmptyInputOk) {
|
| @@ -451,7 +472,7 @@ TEST_F(SdchFilterTest, BasicDictionary) {
|
| std::vector<Filter::FilterType> filter_types;
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| - filter_context()->SetURL(url);
|
| + SetupFilterContextWithGURL(url);
|
|
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| @@ -488,7 +509,8 @@ TEST_F(SdchFilterTest, NoDecodeHttps) {
|
| std::vector<Filter::FilterType> filter_types;
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| - filter_context()->SetURL(GURL("https://" + kSampleDomain));
|
| + GURL filter_context_gurl("https://" + kSampleDomain);
|
| + SetupFilterContextWithGURL(GURL("https://" + kSampleDomain));
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| const size_t feed_block_size(100);
|
| @@ -518,7 +540,7 @@ TEST_F(SdchFilterTest, NoDecodeFtp) {
|
| std::vector<Filter::FilterType> filter_types;
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| - filter_context()->SetURL(GURL("ftp://" + kSampleDomain));
|
| + SetupFilterContextWithGURL(GURL("ftp://" + kSampleDomain));
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| const size_t feed_block_size(100);
|
| @@ -544,7 +566,7 @@ TEST_F(SdchFilterTest, NoDecodeFileColon) {
|
| std::vector<Filter::FilterType> filter_types;
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| - filter_context()->SetURL(GURL("file://" + kSampleDomain));
|
| + SetupFilterContextWithGURL(GURL("file://" + kSampleDomain));
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| const size_t feed_block_size(100);
|
| @@ -570,7 +592,7 @@ TEST_F(SdchFilterTest, NoDecodeAboutColon) {
|
| std::vector<Filter::FilterType> filter_types;
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| - filter_context()->SetURL(GURL("about://" + kSampleDomain));
|
| + SetupFilterContextWithGURL(GURL("about://" + kSampleDomain));
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| const size_t feed_block_size(100);
|
| @@ -596,7 +618,7 @@ TEST_F(SdchFilterTest, NoDecodeJavaScript) {
|
| std::vector<Filter::FilterType> filter_types;
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| - filter_context()->SetURL(GURL("javascript://" + kSampleDomain));
|
| + SetupFilterContextWithGURL(GURL("javascript://" + kSampleDomain));
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| const size_t feed_block_size(100);
|
| @@ -622,7 +644,7 @@ TEST_F(SdchFilterTest, CanStillDecodeHttp) {
|
| std::vector<Filter::FilterType> filter_types;
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| - filter_context()->SetURL(GURL("http://" + kSampleDomain));
|
| + SetupFilterContextWithGURL(GURL("http://" + kSampleDomain));
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| const size_t feed_block_size(100);
|
| @@ -651,7 +673,7 @@ TEST_F(SdchFilterTest, CrossDomainDictionaryUse) {
|
| // Decode with content arriving from the "wrong" domain.
|
| // This tests SdchManager::CanSet().
|
| GURL wrong_domain_url("http://www.wrongdomain.com");
|
| - filter_context()->SetURL(wrong_domain_url);
|
| + SetupFilterContextWithGURL(wrong_domain_url);
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| size_t feed_block_size = 100;
|
| @@ -696,7 +718,7 @@ TEST_F(SdchFilterTest, DictionaryPathValidation) {
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| // Test decode the path data, arriving from a valid path.
|
| - filter_context()->SetURL(GURL(url_string + path));
|
| + SetupFilterContextWithGURL(GURL(url_string + path));
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| size_t feed_block_size = 100;
|
| @@ -708,7 +730,7 @@ TEST_F(SdchFilterTest, DictionaryPathValidation) {
|
| EXPECT_EQ(output, expanded_);
|
|
|
| // Test decode the path data, arriving from a invalid path.
|
| - filter_context()->SetURL(GURL(url_string));
|
| + SetupFilterContextWithGURL(GURL(url_string));
|
| filter.reset(Filter::Factory(filter_types, *filter_context()));
|
|
|
| feed_block_size = 100;
|
| @@ -753,7 +775,7 @@ TEST_F(SdchFilterTest, DictionaryPortValidation) {
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| // Test decode the port data, arriving from a valid port.
|
| - filter_context()->SetURL(GURL(url_string + ":" + port));
|
| + SetupFilterContextWithGURL(GURL(url_string + ":" + port));
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| size_t feed_block_size = 100;
|
| @@ -764,7 +786,7 @@ TEST_F(SdchFilterTest, DictionaryPortValidation) {
|
| EXPECT_EQ(output, expanded_);
|
|
|
| // Test decode the port data, arriving from a valid (default) port.
|
| - filter_context()->SetURL(GURL(url_string)); // Default port.
|
| + SetupFilterContextWithGURL(GURL(url_string)); // Default port.
|
| filter.reset(Filter::Factory(filter_types, *filter_context()));
|
|
|
| feed_block_size = 100;
|
| @@ -775,7 +797,7 @@ TEST_F(SdchFilterTest, DictionaryPortValidation) {
|
| EXPECT_EQ(output, expanded_);
|
|
|
| // Test decode the port data, arriving from a invalid port.
|
| - filter_context()->SetURL(GURL(url_string + ":" + port + "1"));
|
| + SetupFilterContextWithGURL(GURL(url_string + ":" + port + "1"));
|
| filter.reset(Filter::Factory(filter_types, *filter_context()));
|
|
|
| feed_block_size = 100;
|
| @@ -884,7 +906,7 @@ TEST_F(SdchFilterTest, FilterChaining) {
|
| CHECK_GT(kLargeInputBufferSize, gzip_compressed_sdch.size());
|
| CHECK_GT(kLargeInputBufferSize, sdch_compressed.size());
|
| CHECK_GT(kLargeInputBufferSize, expanded_.size());
|
| - filter_context()->SetURL(url);
|
| + SetupFilterContextWithGURL(url);
|
| scoped_ptr<Filter> filter(
|
| SdchFilterChainingTest::Factory(filter_types, *filter_context(),
|
| kLargeInputBufferSize));
|
| @@ -962,16 +984,15 @@ TEST_F(SdchFilterTest, DefaultGzipIfSdch) {
|
| filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
|
|
| filter_context()->SetMimeType("anything/mime");
|
| - filter_context()->SetSdchResponse(true);
|
| + SetupFilterContextWithGURL(url);
|
| +
|
| Filter::FixupEncodingTypes(*filter_context(), &filter_types);
|
| ASSERT_EQ(filter_types.size(), 2u);
|
| EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH);
|
| EXPECT_EQ(filter_types[1], Filter::FILTER_TYPE_GZIP_HELPING_SDCH);
|
|
|
| // First try with a large buffer (larger than test input, or compressed data).
|
| - filter_context()->SetURL(url);
|
| - scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
| -
|
| + scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| // Verify that chained filter is waiting for data.
|
| char tiny_output_buffer[10];
|
| @@ -1020,7 +1041,7 @@ TEST_F(SdchFilterTest, AcceptGzipSdchIfGzip) {
|
| filter_types.push_back(Filter::FILTER_TYPE_GZIP);
|
|
|
| filter_context()->SetMimeType("anything/mime");
|
| - filter_context()->SetSdchResponse(true);
|
| + SetupFilterContextWithGURL(url);
|
| Filter::FixupEncodingTypes(*filter_context(), &filter_types);
|
| ASSERT_EQ(filter_types.size(), 3u);
|
| EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH_POSSIBLE);
|
| @@ -1028,10 +1049,8 @@ TEST_F(SdchFilterTest, AcceptGzipSdchIfGzip) {
|
| EXPECT_EQ(filter_types[2], Filter::FILTER_TYPE_GZIP);
|
|
|
| // First try with a large buffer (larger than test input, or compressed data).
|
| - filter_context()->SetURL(url);
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| -
|
| // Verify that chained filter is waiting for data.
|
| char tiny_output_buffer[10];
|
| int tiny_output_size = sizeof(tiny_output_buffer);
|
| @@ -1077,17 +1096,15 @@ TEST_F(SdchFilterTest, DefaultSdchGzipIfEmpty) {
|
| std::vector<Filter::FilterType> filter_types;
|
|
|
| filter_context()->SetMimeType("anything/mime");
|
| - filter_context()->SetSdchResponse(true);
|
| + SetupFilterContextWithGURL(url);
|
| Filter::FixupEncodingTypes(*filter_context(), &filter_types);
|
| ASSERT_EQ(filter_types.size(), 2u);
|
| EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH_POSSIBLE);
|
| EXPECT_EQ(filter_types[1], Filter::FILTER_TYPE_GZIP_HELPING_SDCH);
|
|
|
| // First try with a large buffer (larger than test input, or compressed data).
|
| - filter_context()->SetURL(url);
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| -
|
| // Verify that chained filter is waiting for data.
|
| char tiny_output_buffer[10];
|
| int tiny_output_size = sizeof(tiny_output_buffer);
|
| @@ -1138,7 +1155,7 @@ TEST_F(SdchFilterTest, AcceptGzipGzipSdchIfGzip) {
|
| filter_types.push_back(Filter::FILTER_TYPE_GZIP);
|
|
|
| filter_context()->SetMimeType("anything/mime");
|
| - filter_context()->SetSdchResponse(true);
|
| + SetupFilterContextWithGURL(url);
|
| Filter::FixupEncodingTypes(*filter_context(), &filter_types);
|
| ASSERT_EQ(filter_types.size(), 3u);
|
| EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH_POSSIBLE);
|
| @@ -1146,7 +1163,6 @@ TEST_F(SdchFilterTest, AcceptGzipGzipSdchIfGzip) {
|
| EXPECT_EQ(filter_types[2], Filter::FILTER_TYPE_GZIP);
|
|
|
| // First try with a large buffer (larger than test input, or compressed data).
|
| - filter_context()->SetURL(url);
|
| scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
|
|
| // Verify that chained filter is waiting for data.
|
| @@ -1173,4 +1189,58 @@ TEST_F(SdchFilterTest, AcceptGzipGzipSdchIfGzip) {
|
| EXPECT_EQ(output, expanded_);
|
| }
|
|
|
| +// Test to make sure we decode properly with an unexpected dictionary.
|
| +TEST_F(SdchFilterTest, UnexpectedDictionary) {
|
| + // Setup a dictionary, add it to the filter context, and create a filter
|
| + // based on that dictionary.
|
| + const std::string kSampleDomain = "sdchtest.com";
|
| + std::string dictionary(NewSdchDictionary(kSampleDomain));
|
| + std::string url_string = "http://" + kSampleDomain;
|
| + GURL url(url_string);
|
| + EXPECT_TRUE(AddSdchDictionary(dictionary, url));
|
| +
|
| + SetupFilterContextWithGURL(url);
|
| +
|
| + std::vector<Filter::FilterType> filter_types;
|
| + filter_types.push_back(Filter::FILTER_TYPE_SDCH);
|
| + scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
|
| +
|
| + // Setup another dictionary, expired. Don't add it to the filter context.
|
| + // Delete stored dictionaries first to handle platforms which only
|
| + // have room for a single dictionary.
|
| + sdch_manager_->ClearData();
|
| + std::string expired_dictionary(NewSdchExpiredDictionary(kSampleDomain));
|
| +
|
| + // Don't use the Helper function since its insertion check is indeterminate
|
| + // for a Max-Age: 0 dictionary.
|
| + sdch_manager_->AddSdchDictionary(expired_dictionary, url);
|
| +
|
| + std::string client_hash;
|
| + std::string server_hash;
|
| + SdchManager::GenerateHash(expired_dictionary, &client_hash, &server_hash);
|
| +
|
| + // Make sure Max-Age: 0 shows up as expired.
|
| + scoped_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock);
|
| + clock->SetNow(base::Time::Now());
|
| + clock->Advance(base::TimeDelta::FromMinutes(5));
|
| + SdchProblemCode problem_code;
|
| + scoped_ptr<SdchManager::DictionarySet> hash_set(
|
| + sdch_manager_->GetDictionarySetByHash(
|
| + url, server_hash, &problem_code).Pass());
|
| + ASSERT_TRUE(hash_set);
|
| + ASSERT_EQ(SDCH_OK, problem_code);
|
| +
|
| + const_cast<SdchManager::Dictionary*>(
|
| + hash_set->Dictionary(server_hash))->SetClockForTesting(
|
| + clock.Pass());
|
| +
|
| + // Encode output with the second dictionary.
|
| + std::string sdch_compressed(NewSdchCompressedData(expired_dictionary));
|
| +
|
| + // See if the filter decodes it.
|
| + std::string output;
|
| + EXPECT_TRUE(FilterTestData(sdch_compressed, 100, 100, filter.get(), &output));
|
| + EXPECT_EQ(expanded_, output);
|
| +}
|
| +
|
| } // namespace net
|
|
|