103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file.
403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// End-to-end SDCH tests.  Uses the embedded test server to return SDCH
603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// results
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/base64.h"
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/bind.h"
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/callback.h"
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/command_line.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/files/scoped_temp_dir.h"
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/weak_ptr.h"
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/path_service.h"
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/run_loop.h"
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/strings/string_tokenizer.h"
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/strings/string_util.h"
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/strings/stringprintf.h"
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/browser_process.h"
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/browsing_data/browsing_data_helper.h"
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/browsing_data/browsing_data_remover.h"
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h"
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/common/content_switches.h"
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/test/test_utils.h"
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "crypto/sha2.h"
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/base/sdch_manager.h"
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/http/http_response_headers.h"
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h"
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/test/embedded_test_server/http_request.h"
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/test/embedded_test_server/http_response.h"
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/url_request/url_fetcher.h"
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/url_request/url_request_context.h"
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "sdch/open-vcdiff/src/google/vcencoder.h"
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(OS_CHROMEOS)
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chromeos/chromeos_switches.h"
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace {
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)typedef std::vector<net::test_server::HttpRequest> RequestVector;
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)typedef std::map<std::string, std::string> HttpRequestHeaderMap;
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Credit Alfred, Lord Tennyson
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)static const char kSampleData[] = "<html><body><pre>"
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "There lies the port; the vessel puffs her sail:\n"
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "There gloom the dark, broad seas. My mariners,\n"
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Souls that have toil'd, and wrought, and thought with me—\n"
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "That ever with a frolic welcome took\n"
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "The thunder and the sunshine, and opposed\n"
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Free hearts, free foreheads—you and I are old;\n"
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Old age hath yet his honour and his toil;\n"
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Death closes all: but something ere the end,\n"
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Some work of noble note, may yet be done,\n"
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Not unbecoming men that strove with Gods.\n"
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "The lights begin to twinkle from the rocks:\n"
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "The long day wanes: the slow moon climbs: the deep\n"
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Moans round with many voices. Come, my friends,\n"
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "'T is not too late to seek a newer world.\n"
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Push off, and sitting well in order smite\n"
7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "The sounding furrows; for my purpose holds\n"
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "To sail beyond the sunset, and the baths\n"
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Of all the western stars, until I die.\n"
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "It may be that the gulfs will wash us down:\n"
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "It may be we shall touch the Happy Isles,\n"
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "And see the great Achilles, whom we knew.\n"
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Tho' much is taken, much abides; and tho'\n"
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "We are not now that strength which in old days\n"
8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Moved earth and heaven, that which we are, we are;\n"
8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "One equal temper of heroic hearts,\n"
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Made weak by time and fate, but strong in will\n"
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "To strive, to seek, to find, and not to yield.\n"
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "</pre></body></html>";
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Random selection of lines from above, to allow some encoding, but
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// not a trivial encoding.
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)static const char kDictionaryContents[] =
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "The thunder and the sunshine, and opposed\n"
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "To sail beyond the sunset, and the baths\n"
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Of all the western stars, until I die.\n"
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Made weak by time and fate, but strong in will\n"
9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Moans round with many voices. Come, my friends,\n"
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "The lights begin to twinkle from the rocks:";
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)static const char kDictionaryURLPath[] = "/dict";
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)static const char kDataURLPath[] = "/data";
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Scans in a case-insensitive way for |header| in |map|,
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// returning true if found and setting |*value| to the value
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// of that header.  Does not handle multiple instances of the same
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// header.
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool GetRequestHeader(const HttpRequestHeaderMap& map,
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                      const char* header,
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                      std::string* value) {
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (HttpRequestHeaderMap::const_iterator it = map.begin();
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)       it != map.end(); ++it) {
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!base::strcasecmp(it->first.c_str(), header)) {
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      *value = it->second;
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return true;
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return false;
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Do a URL-safe base64 encoding.  See the SDCH spec "Dictionary Identifier"
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// section, and RFC 3548 section 4.
12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void SafeBase64Encode(const std::string& input_value, std::string* output) {
12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(output);
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::Base64Encode(input_value, output);
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::replace(output->begin(), output->end(), '+', '-');
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::replace(output->begin(), output->end(), '/', '_');
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Class that bundles responses for an EmbeddedTestServer().
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Dictionary is at <domain>/dict, data at <domain>/data.
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// The data is sent SDCH encoded if that's allowed by protoocol.
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class SdchResponseHandler {
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public:
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Do initial preparation so that SDCH requests can be handled.
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  explicit SdchResponseHandler(std::string domain)
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      : cache_sdch_response_(false),
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        weak_ptr_factory_(this) {
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Dictionary
13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    sdch_dictionary_contents_ = "Domain: ";
13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    sdch_dictionary_contents_ += domain;
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    sdch_dictionary_contents_ += "\n\n";
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    sdch_dictionary_contents_ += kDictionaryContents;
14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Dictionary hash for client and server.
14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    char binary_hash[32];
14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    crypto::SHA256HashString(sdch_dictionary_contents_, binary_hash,
14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             sizeof(binary_hash));
14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    SafeBase64Encode(std::string(&binary_hash[0], 6), &dictionary_client_hash_);
14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    SafeBase64Encode(std::string(&binary_hash[6], 6), &dictionary_server_hash_);
14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Encoded response.
15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    open_vcdiff::HashedDictionary vcdiff_dictionary(
15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        kDictionaryContents, strlen(kDictionaryContents));
15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool result = vcdiff_dictionary.Init();
15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK(result);
15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    open_vcdiff::VCDiffStreamingEncoder encoder(&vcdiff_dictionary, 0, false);
15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    encoded_data_ = dictionary_server_hash_;
15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    encoded_data_ += '\0';
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    result = encoder.StartEncoding(&encoded_data_);
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK(result);
15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    result = encoder.EncodeChunk(
16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        kSampleData, strlen(kSampleData), &encoded_data_);
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK(result);
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    result = encoder.FinishEncoding(&encoded_data_);
16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK(result);
16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  static bool ClientIsAdvertisingSdchEncoding(const HttpRequestHeaderMap& map) {
16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::string value;
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!GetRequestHeader(map, "accept-encoding", &value))
16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return false;
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::StringTokenizer tokenizer(value, " ,");
17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    while (tokenizer.GetNext()) {
17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      if (base::strcasecmp(tokenizer.token().c_str(), "sdch"))
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        return true;
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool ShouldRespondWithSdchEncoding(const HttpRequestHeaderMap& map) {
17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::string value;
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!GetRequestHeader(map, "avail-dictionary", &value))
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return false;
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return value == dictionary_client_hash_;
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<net::test_server::HttpResponse> HandleRequest(
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      const net::test_server::HttpRequest& request) {
18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_vector_.push_back(request);
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<net::test_server::BasicHttpResponse> response(
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        new net::test_server::BasicHttpResponse);
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (request.relative_url == kDataURLPath) {
19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      if (ShouldRespondWithSdchEncoding(request.headers)) {
19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // Note that chrome doesn't advertise accepting SDCH encoding
19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // for POSTs (because the meta-refresh hack would break a POST),
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // but that's not for the server to enforce.
19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        DCHECK_NE(encoded_data_, "");
19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        response->set_content_type("text/html");
19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        response->set_content(encoded_data_);
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        response->AddCustomHeader("Content-Encoding", "sdch");
20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // We allow tests to set caching on the sdch response,
20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // so that we can force an encoded response with no
20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // dictionary.
20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        if (cache_sdch_response_)
20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          response->AddCustomHeader("Cache-Control", "max-age=3600");
20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        else
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          response->AddCustomHeader("Cache-Control", "no-store");
20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      } else {
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        response->set_content_type("text/plain");
20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        response->set_content(kSampleData);
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        if (ClientIsAdvertisingSdchEncoding(request.headers))
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          response->AddCustomHeader("Get-Dictionary", kDictionaryURLPath);
21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // We never cache the plain data response, to make it
21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // easy to refresh after we get the dictionary.
21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        response->AddCustomHeader("Cache-Control", "no-store");
21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      }
21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    } else {
21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      DCHECK_EQ(request.relative_url, kDictionaryURLPath);
21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      DCHECK_NE(sdch_dictionary_contents_, "");
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      response->set_content_type("application/x-sdch-dictionary");
22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      response->set_content(sdch_dictionary_contents_);
22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::vector<base::Closure> callbacks;
22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    callbacks.swap(callback_vector_);
22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    for (std::vector<base::Closure>::iterator it = callbacks.begin();
22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         it != callbacks.end(); ++it) {
22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      it->Run();
22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return response.PassAs<net::test_server::HttpResponse>();
22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void WaitAndGetRequestVector(int num_requests,
23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                               base::Closure callback,
23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                               RequestVector* v) {
23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK_LT(0, num_requests);
23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (static_cast<size_t>(num_requests) > request_vector_.size()) {
23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      callback_vector_.push_back(
23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          base::Bind(&SdchResponseHandler::WaitAndGetRequestVector,
23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr(), num_requests,
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     callback, v));
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return;
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    *v = request_vector_;
24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    content::BrowserThread::PostTask(
24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        content::BrowserThread::UI, FROM_HERE, callback);
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void set_cache_sdch_response(bool cache_sdch_response) {
24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    cache_sdch_response_ = cache_sdch_response;
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private:
25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool cache_sdch_response_;
25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string encoded_data_;
25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string sdch_dictionary_contents_;
25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string dictionary_client_hash_;
25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string dictionary_server_hash_;
25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  RequestVector request_vector_;
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<base::Closure> callback_vector_;
25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::WeakPtrFactory<SdchResponseHandler> weak_ptr_factory_;
26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class SdchBrowserTest : public InProcessBrowserTest, net::URLFetcherDelegate {
26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public:
26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  static const char kTestHost[];
26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SdchBrowserTest()
26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      : response_handler_(kTestHost),
26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        url_request_context_getter_(NULL),
26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        url_fetch_complete_(false),
27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        waiting_(false) {}
27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Helper functions for fetching data.
27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void FetchUrlDetailed(GURL url, net::URLRequestContextGetter* getter) {
27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    url_fetch_complete_ = false;
27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    fetcher_.reset(net::URLFetcher::Create(url, net::URLFetcher::GET, this));
27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    fetcher_->SetRequestContext(getter);
27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    fetcher_->Start();
27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!url_fetch_complete_) {
28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      waiting_ = true;
28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      content::RunMessageLoop();
28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      waiting_ = false;
28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CHECK(url_fetch_complete_);
28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void FetchUrl(GURL url) {
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FetchUrlDetailed(url, url_request_context_getter_.get());
28903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const net::URLRequestStatus& FetcherStatus() const {
29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return fetcher_->GetStatus();
29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  int FetcherResponseCode() const {
29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return (fetcher_->GetStatus().status() == net::URLRequestStatus::SUCCESS ?
29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            fetcher_->GetResponseCode() : 0);
29803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
29903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const net::HttpResponseHeaders* FetcherResponseHeaders() const {
30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return (fetcher_->GetStatus().status() == net::URLRequestStatus::SUCCESS ?
30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            fetcher_->GetResponseHeaders() : NULL);
30303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
30403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string FetcherResponseContents() const {
30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::string contents;
30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (fetcher_->GetStatus().status() == net::URLRequestStatus::SUCCESS)
30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      CHECK(fetcher_->GetResponseAsString(&contents));
30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return contents;
31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Get the data from the server.  Return value is success/failure of the
31303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // data operation, |*sdch_encoding_used| indicates whether or not the
31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // data was retrieved with sdch encoding.
31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // This is done through FetchUrl(), so the various helper functions
31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // will have valid status if it returns successfully.
31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool GetDataDetailed(net::URLRequestContextGetter* getter,
31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                       bool* sdch_encoding_used) {
31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    FetchUrlDetailed(
32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL(base::StringPrintf(
32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            "http://%s:%d%s", kTestHost, test_server_port(), kDataURLPath)),
32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        getter);
32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS, FetcherStatus().status())
32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        << "Error code is " << FetcherStatus().error();
32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(200, FetcherResponseCode());
32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(kSampleData, FetcherResponseContents());
32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (net::URLRequestStatus::SUCCESS != FetcherStatus().status() ||
32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        200 != FetcherResponseCode()) {
33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      *sdch_encoding_used = false;
33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return false;
33203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
33403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    *sdch_encoding_used =
33503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FetcherResponseHeaders()->HasHeaderValue("Content-Encoding", "sdch");
33603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
33703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (FetcherResponseContents() != kSampleData)
33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return false;
33903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
34003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return true;
34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
34203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
34303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool GetData(bool* sdch_encoding_used) {
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return GetDataDetailed(url_request_context_getter_.get(),
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           sdch_encoding_used);
34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
34803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Client information and control.
34903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
35003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  int GetNumberOfDictionaryFetches(Profile* profile) {
35103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int fetches = -1;
35203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::RunLoop run_loop;
35303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    content::BrowserThread::PostTaskAndReply(
35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        content::BrowserThread::IO, FROM_HERE,
35503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(&SdchBrowserTest::GetNumberOfDictionaryFetchesOnIOThread,
35603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Unretained(profile->GetRequestContext()),
35703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   &fetches),
35803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        run_loop.QuitClosure());
35903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    run_loop.Run();
36003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK_NE(-1, fetches);
36103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return fetches;
36203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
36303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
36403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void BrowsingDataRemoveAndWait(int remove_mask) {
36503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    BrowsingDataRemover* remover = BrowsingDataRemover::CreateForPeriod(
36603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        browser()->profile(), BrowsingDataRemover::LAST_HOUR);
36703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    BrowsingDataRemoverCompletionObserver completion_observer(remover);
36803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
36903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    completion_observer.BlockUntilCompletion();
37003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
37103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
37203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Something of a cheat; nuke the dictionaries off the SdchManager without
37303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // touching the cache (which browsing data remover would do).
37403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void NukeSdchDictionaries() {
37503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::RunLoop run_loop;
37603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    content::BrowserThread::PostTaskAndReply(
37703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        content::BrowserThread::IO, FROM_HERE,
37803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(&SdchBrowserTest::NukeSdchDictionariesOnIOThread,
37903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   url_request_context_getter_),
38003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        run_loop.QuitClosure());
38103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    run_loop.Run();
38203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
38303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
38403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Create a second browser based on a second profile to work within
38503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // multi-profile.
38603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool SetupSecondBrowser() {
38703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::FilePath user_data_dir;
38803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
39003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!second_profile_data_dir_.CreateUniqueTempDirUnderPath(user_data_dir))
39103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return false;
39203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
39303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    second_profile_ = g_browser_process->profile_manager()->GetProfile(
39403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        second_profile_data_dir_.path());
39503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!second_profile_) return false;
39603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
39703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    second_browser_ = new Browser(Browser::CreateParams(
39803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        second_profile_, browser()->host_desktop_type()));
39903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!second_browser_) return false;
40003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
40103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    chrome::AddSelectedTabWithURL(second_browser_,
40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                  GURL(url::kAboutBlankURL),
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
40403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    content::WaitForLoadStop(
40503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        second_browser_->tab_strip_model()->GetActiveWebContents());
40603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    second_browser_->window()->Show();
40703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
40803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return true;
40903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
41003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
41103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Browser* second_browser() { return second_browser_; }
41203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
41303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Server information and control.
41403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
41503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void WaitAndGetTestVector(int num_requests, RequestVector* result) {
41603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::RunLoop run_loop;
41703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    content::BrowserThread::PostTask(
41803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        content::BrowserThread::IO, FROM_HERE,
41903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(&SdchResponseHandler::WaitAndGetRequestVector,
42003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Unretained(&response_handler_),
42103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   num_requests,
42203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   run_loop.QuitClosure(),
42303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   result));
42403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    run_loop.Run();
42503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
42603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
42703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  int test_server_port() { return test_server_.port(); }
42803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
42903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void SetSdchCacheability(bool cache_sdch_response) {
43003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::RunLoop run_loop;
43103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    content::BrowserThread::PostTaskAndReply(
43203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        content::BrowserThread::IO, FROM_HERE,
43303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(&SdchResponseHandler::set_cache_sdch_response,
43403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Unretained(&response_handler_),
43503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   cache_sdch_response),
43603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        run_loop.QuitClosure());
43703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    run_loop.Run();
43803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
43903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
44003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Helper function for common test pattern.
44103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  //
44203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // This function gets the data, confirms that the initial sending of the
44303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // data included a dictionary advertisement, that that advertisement
44403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // resulted in queueing a dictionary fetch, forces that fetch to
44503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // go through, and confirms that a follow-on data load uses SDCH
44603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // encoding.  Returns true if the entire sequence of events occurred.
44703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool ForceSdchDictionaryLoad(Browser* browser) {
44803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool sdch_encoding_used = true;
44903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool data_gotten = GetDataDetailed(
45003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        browser->profile()->GetRequestContext(), &sdch_encoding_used);
45103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_TRUE(data_gotten);
45203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!data_gotten) return false;
45303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_FALSE(sdch_encoding_used);
45403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
45503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Confirm that we were told to get the dictionary
45603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const net::HttpResponseHeaders* headers = FetcherResponseHeaders();
45703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::string value;
45803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool have_dict_header =
45903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        headers->EnumerateHeader(NULL, "Get-Dictionary", &value);
46003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_TRUE(have_dict_header);
46103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!have_dict_header) return false;
46203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
46303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // If the above didn't result in a dictionary fetch being queued, the
46403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // rest of the test will time out.  Avoid that.
46503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int num_fetches = GetNumberOfDictionaryFetches(browser->profile());
46603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(1, num_fetches);
46703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (1 != num_fetches) return false;
46803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
46903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Wait until the dictionary fetch actually happens.
47003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    RequestVector request_vector;
47103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    WaitAndGetTestVector(2, &request_vector);
47203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(request_vector[1].relative_url, kDictionaryURLPath);
47303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (request_vector[1].relative_url != kDictionaryURLPath) return false;
47403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
47503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Do a round trip to the server ignoring the encoding, presuming
47603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // that if we've gotten data to this thread, the dictionary's made
47703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // it into the SdchManager.
47803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    data_gotten = GetDataDetailed(
47903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        browser->profile()->GetRequestContext(), &sdch_encoding_used);
48003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_TRUE(data_gotten);
48103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!data_gotten) return false;
48203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
48303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Now data fetches should be SDCH encoded.
48403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    sdch_encoding_used = false;
48503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    data_gotten = GetDataDetailed(
48603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        browser->profile()->GetRequestContext(), &sdch_encoding_used);
48703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_TRUE(data_gotten);
48803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_TRUE(sdch_encoding_used);
48903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
49003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!data_gotten || !sdch_encoding_used) return false;
49103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
49203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Confirm the request vector looks at this point as expected.
49303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    WaitAndGetTestVector(4, &request_vector);
49403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(4u, request_vector.size());
49503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(request_vector[2].relative_url, kDataURLPath);
49603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(request_vector[3].relative_url, kDataURLPath);
49703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return (4u == request_vector.size() &&
49803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            request_vector[2].relative_url == kDataURLPath &&
49903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            request_vector[3].relative_url == kDataURLPath);
50003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
50103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
50203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private:
50303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  static void NukeSdchDictionariesOnIOThread(
50403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      net::URLRequestContextGetter* context_getter) {
50503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
50603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    net::SdchManager* sdch_manager =
50703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        context_getter->GetURLRequestContext()->sdch_manager();
50803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK(sdch_manager);
50903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    sdch_manager->ClearData();
51003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
51103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
51203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  static void GetNumberOfDictionaryFetchesOnIOThread(
51303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      net::URLRequestContextGetter* url_request_context_getter,
51403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      int* result) {
51503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
51603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    net::SdchManager* sdch_manager =
51703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        url_request_context_getter->GetURLRequestContext()->sdch_manager();
51803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DCHECK(sdch_manager);
51903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    *result = sdch_manager->GetFetchesCountForTesting();
52003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
52103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
52203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // InProcessBrowserTest
52303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
52403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    command_line->AppendSwitchASCII(
52503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        switches::kHostResolverRules,
52603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "MAP " + std::string(kTestHost) + " 127.0.0.1");
52703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(OS_CHROMEOS)
52803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    command_line->AppendSwitch(
52903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        chromeos::switches::kIgnoreUserProfileMappingForTests);
53003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif
53103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
53203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
53303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
53403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    test_server_.RegisterRequestHandler(
53503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(&SdchResponseHandler::HandleRequest,
53603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Unretained(&response_handler_)));
53703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CHECK(test_server_.InitializeAndWaitUntilReady());
53803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    url_request_context_getter_ = browser()->profile()->GetRequestContext();
53903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
54003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
54103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void TearDownOnMainThread() OVERRIDE {
54203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CHECK(test_server_.ShutdownAndWaitUntilComplete());
54303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
54403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
54503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // URLFetcherDelegate
54603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE {
54703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    url_fetch_complete_ = true;
54803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (waiting_)
54903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::MessageLoopForUI::current()->Quit();
55003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
55103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
55203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SdchResponseHandler response_handler_;
55303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  net::test_server::EmbeddedTestServer test_server_;
55403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
55503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<net::URLFetcher> fetcher_;
55603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool url_fetch_complete_;
55703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool waiting_;
55803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::ScopedTempDir second_profile_data_dir_;
55903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Profile* second_profile_;
56003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Browser* second_browser_;
56103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
56203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
56303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const char SdchBrowserTest::kTestHost[] = "our.test.host.com";
56403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
56503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Confirm that after getting a dictionary, calling the browsing
56603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// data remover renders it unusable.  Also (in calling
56703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// ForceSdchDictionaryLoad()) servers as a smoke test for SDCH.
56803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(SdchBrowserTest, BrowsingDataRemover) {
56903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_TRUE(ForceSdchDictionaryLoad(browser()));
57003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
57103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Confirm browsing data remover without removing the cache leaves
57203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // SDCH alone.
57303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  BrowsingDataRemoveAndWait(BrowsingDataRemover::REMOVE_ALL &
57403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            ~BrowsingDataRemover::REMOVE_CACHE);
57503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool sdch_encoding_used = false;
57603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_TRUE(GetData(&sdch_encoding_used));
57703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(sdch_encoding_used);
57803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
57903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Confirm browsing data remover removing the cache clears SDCH state.
58003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  BrowsingDataRemoveAndWait(BrowsingDataRemover::REMOVE_CACHE);
58103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  sdch_encoding_used = false;
58203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_TRUE(GetData(&sdch_encoding_used));
58303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(sdch_encoding_used);
58403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
58503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
58603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Confirm dictionaries not visible in other profiles.
58703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(SdchBrowserTest, Isolation) {
58803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_TRUE(ForceSdchDictionaryLoad(browser()));
58903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_TRUE(SetupSecondBrowser());
59003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
59103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Data fetches from incognito or separate profiles should not be SDCH
59203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // encoded.
59303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool sdch_encoding_used = true;
59403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Browser* incognito_browser = CreateIncognitoBrowser();
59503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(GetDataDetailed(
59603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      incognito_browser->profile()->GetRequestContext(),
59703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      &sdch_encoding_used));
59803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(sdch_encoding_used);
59903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
60003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  sdch_encoding_used = true;
60103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(GetDataDetailed(
60203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      second_browser()->profile()->GetRequestContext(), &sdch_encoding_used));
60303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(sdch_encoding_used);
60403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
60503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
60603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Confirm a dictionary loaded in incognito isn't visible in the main profile.
60703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(SdchBrowserTest, ReverseIsolation) {
60803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Browser* incognito_browser = CreateIncognitoBrowser();
60903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_TRUE(ForceSdchDictionaryLoad(incognito_browser));
61003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
61103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Data fetches on main browser should not be SDCH encoded.
61203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool sdch_encoding_used = true;
61303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_TRUE(GetData(&sdch_encoding_used));
61403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(sdch_encoding_used);
61503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
61603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
61703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace
618