diff options
author | bengr <bengr@chromium.org> | 2015-02-19 21:23:27 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-20 05:24:05 +0000 |
commit | da6251399179bd88f1641e402bb77d9dfadc51c4 (patch) | |
tree | a9b61ff6e1d64c31ce548354b3dcf88fa1ce371f /components/data_reduction_proxy | |
parent | e397125808a5771d2e05531a03ca1656d77ddbf1 (diff) | |
download | chromium_src-da6251399179bd88f1641e402bb77d9dfadc51c4.zip chromium_src-da6251399179bd88f1641e402bb77d9dfadc51c4.tar.gz chromium_src-da6251399179bd88f1641e402bb77d9dfadc51c4.tar.bz2 |
Add flag to request Data Saver experiment
Adds a command line flag, --data-saver-experiment, that takes
a comma-delimited list of experiments to run. These experiments
are conveyed to the Data Saver proxy via a new Chrome-Proxy
request header directive, "exp".
BUG=452295
Review URL: https://codereview.chromium.org/934973003
Cr-Commit-Position: refs/heads/master@{#317249}
Diffstat (limited to 'components/data_reduction_proxy')
5 files changed, 239 insertions, 345 deletions
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc index 568fafc..16d8690 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc @@ -4,12 +4,11 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h" -#include <vector> - #include "base/bind.h" #include "base/command_line.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_split.h" +#include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -30,12 +29,19 @@ namespace data_reduction_proxy { +namespace { +std::string FormatOption(const std::string& name, const std::string& value) { + return name + "=" + value; +} +} //namespace + const char kSessionHeaderOption[] = "ps"; const char kCredentialsHeaderOption[] = "sid"; const char kBuildNumberHeaderOption[] = "b"; const char kPatchNumberHeaderOption[] = "p"; const char kClientHeaderOption[] = "c"; const char kLoFiHeaderOption[] = "q"; +const char kExperimentsOption[] = "exp"; // The empty version for the authentication protocol. Currently used by // Android webview. @@ -67,9 +73,9 @@ DataReductionProxyRequestOptions::DataReductionProxyRequestOptions( DataReductionProxyParams* params, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner) : client_(GetString(client)), - version_(ChromiumVersion()), data_reduction_proxy_params_(params), network_task_runner_(network_task_runner) { + GetChromiumBuildAndPatch(ChromiumVersion(), &build_, &patch_); } DataReductionProxyRequestOptions::DataReductionProxyRequestOptions( @@ -78,9 +84,9 @@ DataReductionProxyRequestOptions::DataReductionProxyRequestOptions( DataReductionProxyParams* params, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner) : client_(GetString(client)), - version_(version), data_reduction_proxy_params_(params), network_task_runner_(network_task_runner) { + GetChromiumBuildAndPatch(version, &build_, &patch_); } DataReductionProxyRequestOptions::~DataReductionProxyRequestOptions() { @@ -91,6 +97,7 @@ void DataReductionProxyRequestOptions::Init() { UpdateCredentials(); UpdateLoFi(); UpdateVersion(); + UpdateExperiments(); } std::string DataReductionProxyRequestOptions::ChromiumVersion() const { @@ -114,34 +121,40 @@ void DataReductionProxyRequestOptions::GetChromiumBuildAndPatch( } void DataReductionProxyRequestOptions::UpdateVersion() { - std::string build_number; - std::string patch_number; - GetChromiumBuildAndPatch(version_, &build_number, &patch_number); - if (!build_number.empty() && !patch_number.empty()) { - header_options_[kBuildNumberHeaderOption] = build_number; - header_options_[kPatchNumberHeaderOption] = patch_number; - } - if (!client_.empty()) - header_options_[kClientHeaderOption] = client_; + GetChromiumBuildAndPatch(version_, &build_, &patch_); RegenerateRequestHeaderValue(); } void DataReductionProxyRequestOptions::UpdateLoFi() { // LoFi was not enabled, but now is. Add the header option. - if (header_options_.find(kLoFiHeaderOption) == header_options_.end() && + if (lofi_.empty() && DataReductionProxyParams::IsLoFiEnabled()) { - header_options_[kLoFiHeaderOption] = "low"; + lofi_ = "low"; RegenerateRequestHeaderValue(); return; } // LoFi was enabled, but no longer is. Remove the header option. - if (header_options_.find(kLoFiHeaderOption) != header_options_.end() && - !DataReductionProxyParams::IsLoFiEnabled()) { - header_options_.erase(kLoFiHeaderOption); + if (!lofi_.empty() && !DataReductionProxyParams::IsLoFiEnabled()) { + lofi_ = std::string(); RegenerateRequestHeaderValue(); } } +void DataReductionProxyRequestOptions::UpdateExperiments() { + std::string experiments = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + data_reduction_proxy::switches::kDataReductionProxyExperiment); + if (experiments.empty()) + return; + base::StringTokenizer experiment_tokenizer(experiments, ", "); + experiment_tokenizer.set_quote_chars("\""); + while (experiment_tokenizer.GetNext()) { + if (!experiment_tokenizer.token().empty()) + experiments_.push_back(experiment_tokenizer.token()); + } + RegenerateRequestHeaderValue(); +} + // static base::string16 DataReductionProxyRequestOptions::AuthHashForSalt( int64 salt, @@ -228,9 +241,7 @@ void DataReductionProxyRequestOptions::UpdateCredentials() { std::string session; std::string credentials; last_credentials_update_time_ = Now(); - ComputeCredentials(last_credentials_update_time_, &session, &credentials); - header_options_[kSessionHeaderOption] = session; - header_options_[kCredentialsHeaderOption] = credentials; + ComputeCredentials(last_credentials_update_time_, &session_, &credentials_); RegenerateRequestHeaderValue(); } @@ -277,12 +288,18 @@ void DataReductionProxyRequestOptions::MaybeAddRequestHeaderImpl( } void DataReductionProxyRequestOptions::RegenerateRequestHeaderValue() { - std::vector <std::string> options; - for (std::map<std::string, std::string>::iterator - it = header_options_.begin(); it != header_options_.end(); ++it) { - options.push_back(it->first + "=" + it->second); - } - header_value_ = JoinString(options, ", "); + header_value_ = FormatOption(kSessionHeaderOption, session_) + + ", " + FormatOption(kCredentialsHeaderOption, credentials_) + + (client_.empty() ? + "" : ", " + FormatOption(kClientHeaderOption, client_)) + + (build_.empty() || patch_.empty() ? + "" : + ", " + FormatOption(kBuildNumberHeaderOption, build_) + + ", " + FormatOption(kPatchNumberHeaderOption, patch_)) + + (lofi_.empty() ? + "" : ", " + FormatOption(kLoFiHeaderOption, lofi_)); + for (const auto& experiment : experiments_) + header_value_ += ", " + FormatOption(kExperimentsOption, experiment); } } // namespace data_reduction_proxy diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h index 1a9ef79..e11f1de 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h @@ -5,8 +5,8 @@ #ifndef COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_AUTH_REQUEST_HANDLER_H_ #define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_AUTH_REQUEST_HANDLER_H_ -#include <map> #include <string> +#include <vector> #include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" @@ -33,6 +33,7 @@ extern const char kBuildNumberHeaderOption[]; extern const char kPatchNumberHeaderOption[]; extern const char kClientHeaderOption[]; extern const char kLoFiHeaderOption[]; +extern const char kExperimentsOption[]; #if defined(OS_ANDROID) extern const char kAndroidWebViewProtocolVersion[]; @@ -74,8 +75,8 @@ class DataReductionProxyRequestOptions { virtual ~DataReductionProxyRequestOptions(); // Sets |key_| to the default key and initializes the credentials, version, - // client, and lo-fi header values in |header_options_|. Generates the - // |header_value_| string which is concatenated to the Chrome-proxy header. + // client, and lo-fi header values. Generates the |header_value_| string, + // which is concatenated to the Chrome-proxy header. void Init(); // Adds a 'Chrome-Proxy' header to |request_headers| with the data reduction @@ -127,17 +128,7 @@ class DataReductionProxyRequestOptions { private: FRIEND_TEST_ALL_PREFIXES(DataReductionProxyRequestOptionsTest, - AuthorizationOnIOThread); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxyRequestOptionsTest, - AuthorizationIgnoresEmptyKey); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxyRequestOptionsTest, - AuthorizationBogusVersion); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxyRequestOptionsTest, AuthHashForSalt); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxyRequestOptionsTest, - AuthorizationLoFi); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxyRequestOptionsTest, - AuthorizationLoFiOffThenOn); // Returns the version of Chromium that is being used. std::string ChromiumVersion() const; @@ -148,20 +139,23 @@ class DataReductionProxyRequestOptions { std::string* build, std::string* patch) const; - // Uses |version_| and |client_| to update values in |header_options_|. + // Updates client type, build, and patch. void UpdateVersion(); - // Updates the value of LoFi in |header_options_| and regenerates the header - // if necessary. + // Updates the value of LoFi and regenerates the header if necessary. void UpdateLoFi(); + // Update the value of the experiments to be run and regenerate the header if + // necessary. + void UpdateExperiments(); + // Generates a session ID and credentials suitable for authenticating with // the data reduction proxy. void ComputeCredentials(const base::Time& now, std::string* session, std::string* credentials); - // Generates and updates the session ID and credentials in |header_options_|. + // Generates and updates the session ID and credentials. void UpdateCredentials(); // Adds authentication headers only if |expects_ssl| is true and @@ -176,8 +170,7 @@ class DataReductionProxyRequestOptions { // Chrome-proxy header. void RegenerateRequestHeaderValue(); - // Map and string of the request options to be added to the header. - std::map<std::string, std::string> header_options_; + // The Chrome-Proxy header value. std::string header_value_; // Authentication state. @@ -186,6 +179,12 @@ class DataReductionProxyRequestOptions { // Name of the client and version of the data reduction proxy protocol to use. std::string client_; std::string version_; + std::string session_; + std::string credentials_; + std::string build_; + std::string patch_; + std::string lofi_; + std::vector<std::string> experiments_; // The last time the session was updated. Used to ensure that a session is // never used for more than twenty-four hours. diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc index cf5bf46..196b071 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h" #include "base/command_line.h" @@ -89,7 +88,9 @@ class TestDataReductionProxyRequestOptions : DataReductionProxyRequestOptions( client, version, params, loop_proxy) {} - std::string GetDefaultKey() const override { return kTestKey; } + std::string GetDefaultKey() const override { + return kTestKey; + } base::Time Now() const override { return base::Time::UnixEpoch() + now_offset_; @@ -111,365 +112,235 @@ class TestDataReductionProxyRequestOptions base::TimeDelta now_offset_; }; +void SetHeaderExpectations(const std::string& session, + const std::string& credentials, + const std::string& client, + const std::string& build, + const std::string& patch, + const std::string& lofi, + const std::vector<std::string> experiments, + std::string* expected_header) { + std::vector<std::string> expected_options; + if (!session.empty()) { + expected_options.push_back( + std::string(kSessionHeaderOption) + "=" + session); + } + if (!credentials.empty()) { + expected_options.push_back( + std::string(kCredentialsHeaderOption) + "=" + credentials); + } + if (!client.empty()) { + expected_options.push_back( + std::string(kClientHeaderOption) + "=" + client); + } + if (!build.empty()) { + expected_options.push_back( + std::string(kBuildNumberHeaderOption) + "=" + build); + } + if (!patch.empty()) { + expected_options.push_back( + std::string(kPatchNumberHeaderOption) + "=" + patch); + } + if (!lofi.empty()) { + expected_options.push_back( + std::string(kLoFiHeaderOption) + "=" + lofi); + } + for (const auto& experiment : experiments) { + expected_options.push_back( + std::string(kExperimentsOption) + "=" + experiment); + } + if (!expected_options.empty()) + *expected_header = JoinString(expected_options, ", "); +} + } // namespace class DataReductionProxyRequestOptionsTest : public testing::Test { public: - DataReductionProxyRequestOptionsTest() - : loop_proxy_(base::MessageLoopProxy::current().get()) { + DataReductionProxyRequestOptionsTest() { + params_.reset( + new TestDataReductionProxyParams( + DataReductionProxyParams::kAllowed | + DataReductionProxyParams::kFallbackAllowed | + DataReductionProxyParams::kPromoAllowed, + TestDataReductionProxyParams::HAS_EVERYTHING & + ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & + ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)); } - std::map<std::string, std::string> ParseHeader(std::string header) { - std::map<std::string, std::string> header_options; - size_t pos = 0; - std::string name; - std::string value; - std::string equals_delimiter = "="; - std::string comma_delimiter = ", "; - while ((pos = header.find(equals_delimiter)) != std::string::npos) { - name = header.substr(0, pos); - header.erase(0, pos + equals_delimiter.length()); - pos = header.find(comma_delimiter); - if (pos != std::string::npos) { - value = header.substr(0, pos); - header.erase(0, pos + comma_delimiter.length()); - header_options[name] = value; - } - } + void CreateRequestOptions(const std::string& version) { + request_options_.reset( + new TestDataReductionProxyRequestOptions( + kClient, version, params(), loop_proxy())); + request_options_->Init(); + } + + TestDataReductionProxyParams* params() { + return params_.get(); + } - if (!header.empty()) - header_options[name] = header; + base::MessageLoopProxy* loop_proxy() { + return base::MessageLoopProxy::current().get(); + } + + TestDataReductionProxyRequestOptions* request_options() { + return request_options_.get(); + } - return header_options; + void VerifyExpectedHeader(const std::string& proxy_uri, + const std::string& expected_header) { + base::RunLoop().RunUntilIdle(); + net::HttpRequestHeaders headers; + request_options_->MaybeAddRequestHeader( + NULL, + proxy_uri.empty() ? net::ProxyServer() : + net::ProxyServer::FromURI(proxy_uri, net::ProxyServer::SCHEME_HTTP), + &headers); + if (expected_header.empty()) { + EXPECT_FALSE(headers.HasHeader(kChromeProxyHeader)); + return; + } + EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader)); + std::string header_value; + headers.GetHeader(kChromeProxyHeader, &header_value); + EXPECT_EQ(expected_header, header_value); } + private: // Required for MessageLoopProxy::current(). base::MessageLoopForUI loop_; - base::MessageLoopProxy* loop_proxy_; + scoped_ptr<TestDataReductionProxyParams> params_; + scoped_ptr<TestDataReductionProxyRequestOptions> request_options_; }; +TEST_F(DataReductionProxyRequestOptionsTest, AuthHashForSalt) { + std::string salt = "8675309"; // Jenny's number to test the hash generator. + std::string salted_key = salt + kDataReductionProxyKey + salt; + base::string16 expected_hash = base::UTF8ToUTF16(base::MD5String(salted_key)); + EXPECT_EQ(expected_hash, + DataReductionProxyRequestOptions::AuthHashForSalt( + 8675309, kDataReductionProxyKey)); +} + TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationOnIOThread) { - std::map<std::string, std::string> kExpectedHeader; - kExpectedHeader[kSessionHeaderOption] = kExpectedSession2; - kExpectedHeader[kCredentialsHeaderOption] = kExpectedCredentials2; - kExpectedHeader[kBuildNumberHeaderOption] = "2"; - kExpectedHeader[kPatchNumberHeaderOption] = "3"; - kExpectedHeader[kClientHeaderOption] = kClientStr; - - std::map<std::string, std::string> kExpectedHeader2; - kExpectedHeader2[kSessionHeaderOption] = - "86401-1633771873-1633771873-1633771873"; - kExpectedHeader2[kCredentialsHeaderOption] = - "d7c1c34ef6b90303b01c48a6c1db6419"; - kExpectedHeader2[kBuildNumberHeaderOption] = "2"; - kExpectedHeader2[kPatchNumberHeaderOption] = "3"; - kExpectedHeader2[kClientHeaderOption] = kClientStr; - - scoped_ptr<TestDataReductionProxyParams> params; - params.reset( - new TestDataReductionProxyParams( - DataReductionProxyParams::kAllowed | - DataReductionProxyParams::kFallbackAllowed | - DataReductionProxyParams::kPromoAllowed, - TestDataReductionProxyParams::HAS_EVERYTHING & - ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & - ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)); - // loop_proxy_ is just the current message loop. This means loop_proxy_ - // is the network thread used by DataReductionProxyRequestOptions. - TestDataReductionProxyRequestOptions request_options(kClient, - kVersion, - params.get(), - loop_proxy_); - request_options.Init(); + std::string expected_header; + SetHeaderExpectations(kExpectedSession2, kExpectedCredentials2, kClientStr, + kExpectedBuild, kExpectedPatch, std::string(), + std::vector<std::string>(), &expected_header); + + std::string expected_header2; + SetHeaderExpectations("86401-1633771873-1633771873-1633771873", + "d7c1c34ef6b90303b01c48a6c1db6419", kClientStr, + kExpectedBuild, kExpectedPatch, std::string(), + std::vector<std::string>(), &expected_header2); + + CreateRequestOptions(kVersion); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(kExpectedBuild, - request_options.header_options_[kBuildNumberHeaderOption]); - EXPECT_EQ(kExpectedPatch, - request_options.header_options_[kPatchNumberHeaderOption]); - EXPECT_EQ(request_options.key_, kTestKey); - EXPECT_EQ(kExpectedCredentials, - request_options.header_options_[kCredentialsHeaderOption]); - EXPECT_EQ(kExpectedSession, - request_options.header_options_[kSessionHeaderOption]); - EXPECT_EQ(kClientStr, request_options.header_options_[kClientHeaderOption]); // Now set a key. - request_options.SetKeyOnIO(kTestKey2); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(kTestKey2, request_options.key_); - EXPECT_EQ(kExpectedCredentials2, - request_options.header_options_[kCredentialsHeaderOption]); - EXPECT_EQ(kExpectedSession2, - request_options.header_options_[kSessionHeaderOption]); + request_options()->SetKeyOnIO(kTestKey2); // Don't write headers if the proxy is invalid. - net::HttpRequestHeaders headers; - request_options.MaybeAddRequestHeader(NULL, net::ProxyServer(), &headers); - EXPECT_FALSE(headers.HasHeader(kChromeProxyHeader)); + VerifyExpectedHeader(std::string(), std::string()); // Don't write headers with a valid proxy, that's not a data reduction proxy. - request_options.MaybeAddRequestHeader( - NULL, - net::ProxyServer::FromURI(kOtherProxy, net::ProxyServer::SCHEME_HTTP), - &headers); - EXPECT_FALSE(headers.HasHeader(kChromeProxyHeader)); + VerifyExpectedHeader(kOtherProxy, std::string()); // Don't write headers with a valid data reduction ssl proxy. - request_options.MaybeAddRequestHeader( - NULL, - net::ProxyServer::FromURI(params->DefaultSSLOrigin(), - net::ProxyServer::SCHEME_HTTP), - &headers); - EXPECT_FALSE(headers.HasHeader(kChromeProxyHeader)); + VerifyExpectedHeader(params()->DefaultSSLOrigin(), std::string()); // Write headers with a valid data reduction proxy. - request_options.MaybeAddRequestHeader( - NULL, - net::ProxyServer::FromURI(params->DefaultOrigin(), - net::ProxyServer::SCHEME_HTTP), - &headers); - EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader)); - std::string header_value; - headers.GetHeader(kChromeProxyHeader, &header_value); - EXPECT_EQ(kExpectedHeader, ParseHeader(header_value)); + VerifyExpectedHeader(params()->DefaultOrigin(), expected_header); // Write headers with a valid data reduction ssl proxy when one is expected. net::HttpRequestHeaders ssl_headers; - request_options.MaybeAddProxyTunnelRequestHandler( + request_options()->MaybeAddProxyTunnelRequestHandler( net::ProxyServer::FromURI( - params->DefaultSSLOrigin(), + params()->DefaultSSLOrigin(), net::ProxyServer::SCHEME_HTTP).host_port_pair(), &ssl_headers); EXPECT_TRUE(ssl_headers.HasHeader(kChromeProxyHeader)); std::string ssl_header_value; ssl_headers.GetHeader(kChromeProxyHeader, &ssl_header_value); - EXPECT_EQ(kExpectedHeader, ParseHeader(ssl_header_value)); + EXPECT_EQ(expected_header, ssl_header_value); // Fast forward 24 hours. The header should be the same. - request_options.set_offset(base::TimeDelta::FromSeconds(24 * 60 * 60)); - net::HttpRequestHeaders headers2; - // Write headers with a valid data reduction proxy. - request_options.MaybeAddRequestHeader( - NULL, - net::ProxyServer::FromURI(params->DefaultOrigin(), - net::ProxyServer::SCHEME_HTTP), - &headers2); - EXPECT_TRUE(headers2.HasHeader(kChromeProxyHeader)); - std::string header_value2; - headers2.GetHeader(kChromeProxyHeader, &header_value2); - EXPECT_EQ(kExpectedHeader, ParseHeader(header_value2)); + request_options()->set_offset(base::TimeDelta::FromSeconds(24 * 60 * 60)); + VerifyExpectedHeader(params()->DefaultOrigin(), expected_header); // Fast forward one more second. The header should be new. - request_options.set_offset(base::TimeDelta::FromSeconds(24 * 60 * 60 + 1)); - net::HttpRequestHeaders headers3; - // Write headers with a valid data reduction proxy. - request_options.MaybeAddRequestHeader( - NULL, - net::ProxyServer::FromURI(params->DefaultOrigin(), - net::ProxyServer::SCHEME_HTTP), - &headers3); - EXPECT_TRUE(headers3.HasHeader(kChromeProxyHeader)); - std::string header_value3; - headers3.GetHeader(kChromeProxyHeader, &header_value3); - EXPECT_EQ(kExpectedHeader2, ParseHeader(header_value3)); + request_options()->set_offset(base::TimeDelta::FromSeconds(24 * 60 * 60 + 1)); + VerifyExpectedHeader(params()->DefaultOrigin(), expected_header2); } TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationIgnoresEmptyKey) { -scoped_ptr<TestDataReductionProxyParams> params; - params.reset( - new TestDataReductionProxyParams( - DataReductionProxyParams::kAllowed | - DataReductionProxyParams::kFallbackAllowed | - DataReductionProxyParams::kPromoAllowed, - TestDataReductionProxyParams::HAS_EVERYTHING & - ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & - ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)); - // loop_proxy_ is just the current message loop. This means loop_proxy_ - // is the network thread used by DataReductionProxyRequestOptions. - TestDataReductionProxyRequestOptions request_options(kClient, - kVersion, - params.get(), - loop_proxy_); - request_options.Init(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(kExpectedBuild, - request_options.header_options_[kBuildNumberHeaderOption]); - EXPECT_EQ(kExpectedPatch, - request_options.header_options_[kPatchNumberHeaderOption]); - EXPECT_EQ(request_options.key_, kTestKey); - EXPECT_EQ(kExpectedCredentials, - request_options.header_options_[kCredentialsHeaderOption]); - EXPECT_EQ(kExpectedSession, - request_options.header_options_[kSessionHeaderOption]); - EXPECT_EQ(kClientStr, request_options.header_options_[kClientHeaderOption]); + std::string expected_header; + SetHeaderExpectations(kExpectedSession, kExpectedCredentials, kClientStr, + kExpectedBuild, kExpectedPatch, std::string(), + std::vector<std::string>(), &expected_header); + CreateRequestOptions(kVersion); + VerifyExpectedHeader(params()->DefaultOrigin(), expected_header); // Now set an empty key. The auth handler should ignore that, and the key // remains |kTestKey|. - request_options.SetKeyOnIO(""); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(request_options.key_, kTestKey); - EXPECT_EQ(kExpectedCredentials, - request_options.header_options_[kCredentialsHeaderOption]); - EXPECT_EQ(kExpectedSession, - request_options.header_options_[kSessionHeaderOption]); + request_options()->SetKeyOnIO(std::string()); + VerifyExpectedHeader(params()->DefaultOrigin(), expected_header); } TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationBogusVersion) { - std::map<std::string, std::string> kExpectedHeader; - kExpectedHeader[kSessionHeaderOption] = kExpectedSession2; - kExpectedHeader[kCredentialsHeaderOption] = kExpectedCredentials2; - kExpectedHeader[kClientHeaderOption] = kClientStr; - - scoped_ptr<TestDataReductionProxyParams> params; - params.reset( - new TestDataReductionProxyParams( - DataReductionProxyParams::kAllowed | - DataReductionProxyParams::kFallbackAllowed | - DataReductionProxyParams::kPromoAllowed, - TestDataReductionProxyParams::HAS_EVERYTHING & - ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & - ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)); - TestDataReductionProxyRequestOptions request_options(kClient, - kBogusVersion, - params.get(), - loop_proxy_); - request_options.Init(); - EXPECT_TRUE(request_options.header_options_.find(kBuildNumberHeaderOption) == - request_options.header_options_.end()); - EXPECT_TRUE(request_options.header_options_.find(kPatchNumberHeaderOption) == - request_options.header_options_.end()); + std::string expected_header; + SetHeaderExpectations(kExpectedSession2, kExpectedCredentials2, kClientStr, + std::string(), std::string(), std::string(), + std::vector<std::string>(), &expected_header); - // Now set a key. - request_options.SetKeyOnIO(kTestKey2); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(kTestKey2, request_options.key_); - EXPECT_EQ(kExpectedCredentials2, - request_options.header_options_[kCredentialsHeaderOption]); - EXPECT_EQ(kExpectedSession2, - request_options.header_options_[kSessionHeaderOption]); + CreateRequestOptions(kBogusVersion); - net::HttpRequestHeaders headers; - // Write headers with a valid data reduction proxy. - request_options.MaybeAddRequestHeader( - NULL, - net::ProxyServer::FromURI( - params->DefaultOrigin(), - net::ProxyServer::SCHEME_HTTP), - &headers); - EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader)); - std::string header_value; - headers.GetHeader(kChromeProxyHeader, &header_value); - EXPECT_EQ(kExpectedHeader, ParseHeader(header_value)); -} - -TEST_F(DataReductionProxyRequestOptionsTest, AuthHashForSalt) { - std::string salt = "8675309"; // Jenny's number to test the hash generator. - std::string salted_key = salt + kDataReductionProxyKey + salt; - base::string16 expected_hash = base::UTF8ToUTF16(base::MD5String(salted_key)); - EXPECT_EQ(expected_hash, - DataReductionProxyRequestOptions::AuthHashForSalt( - 8675309, kDataReductionProxyKey)); + // Now set a key. + request_options()->SetKeyOnIO(kTestKey2); + VerifyExpectedHeader(params()->DefaultOrigin(), expected_header); } TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationLoFi) { - std::map<std::string, std::string> kExpectedHeader; - kExpectedHeader[kSessionHeaderOption] = kExpectedSession; - kExpectedHeader[kCredentialsHeaderOption] = kExpectedCredentials; - kExpectedHeader[kClientHeaderOption] = kClientStr; - kExpectedHeader[kLoFiHeaderOption] = "low"; - - scoped_ptr<TestDataReductionProxyParams> params; - params.reset( - new TestDataReductionProxyParams( - DataReductionProxyParams::kAllowed | - DataReductionProxyParams::kFallbackAllowed | - DataReductionProxyParams::kPromoAllowed, - TestDataReductionProxyParams::HAS_EVERYTHING & - ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & - ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)); + std::string expected_header; + SetHeaderExpectations(kExpectedSession, kExpectedCredentials, kClientStr, + std::string(), std::string(), "low", + std::vector<std::string>(), &expected_header); base::CommandLine::ForCurrentProcess()->AppendSwitch( data_reduction_proxy::switches::kEnableDataReductionProxyLoFi); - TestDataReductionProxyRequestOptions request_options(kClient, - kBogusVersion, - params.get(), - loop_proxy_); - request_options.Init(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(kTestKey, request_options.key_); - EXPECT_EQ(kExpectedCredentials, - request_options.header_options_[kCredentialsHeaderOption]); - EXPECT_EQ(kExpectedSession, - request_options.header_options_[kSessionHeaderOption]); - - net::HttpRequestHeaders headers; - // Write headers with a valid data reduction proxy. - request_options.MaybeAddRequestHeader( - NULL, - net::ProxyServer::FromURI(params->DefaultOrigin(), - net::ProxyServer::SCHEME_HTTP), - &headers); - EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader)); - std::string header_value; - headers.GetHeader(kChromeProxyHeader, &header_value); - EXPECT_EQ(kExpectedHeader, ParseHeader(header_value)); + CreateRequestOptions(kBogusVersion); + VerifyExpectedHeader(params()->DefaultOrigin(), expected_header); } -TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationLoFiOffThenOn) { - std::map<std::string, std::string> kExpectedHeader; - kExpectedHeader[kSessionHeaderOption] = kExpectedSession; - kExpectedHeader[kCredentialsHeaderOption] = kExpectedCredentials; - kExpectedHeader[kClientHeaderOption] = kClientStr; - - scoped_ptr<TestDataReductionProxyParams> params; - params.reset( - new TestDataReductionProxyParams( - DataReductionProxyParams::kAllowed | - DataReductionProxyParams::kFallbackAllowed | - DataReductionProxyParams::kPromoAllowed, - TestDataReductionProxyParams::HAS_EVERYTHING & - ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & - ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)); - - TestDataReductionProxyRequestOptions request_options(kClient, - kBogusVersion, - params.get(), - loop_proxy_); - request_options.Init(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(kTestKey, request_options.key_); - EXPECT_EQ(kExpectedCredentials, - request_options.header_options_[kCredentialsHeaderOption]); - EXPECT_EQ(kExpectedSession, - request_options.header_options_[kSessionHeaderOption]); - - net::HttpRequestHeaders headers; - // Write headers with a valid data reduction proxy. - request_options.MaybeAddRequestHeader( - NULL, - net::ProxyServer::FromURI(params->DefaultOrigin(), - net::ProxyServer::SCHEME_HTTP), - &headers); - EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader)); - std::string header_value; - headers.GetHeader(kChromeProxyHeader, &header_value); - EXPECT_EQ(kExpectedHeader, ParseHeader(header_value)); - +TEST_F(DataReductionProxyRequestOptionsTest, LoFiOn) { // Add the LoFi command line switch. base::CommandLine::ForCurrentProcess()->AppendSwitch( data_reduction_proxy::switches::kEnableDataReductionProxyLoFi); - kExpectedHeader[kLoFiHeaderOption] = "low"; - - // Write headers with a valid data reduction proxy. - request_options.MaybeAddRequestHeader( - NULL, - net::ProxyServer::FromURI(params->DefaultOrigin(), - net::ProxyServer::SCHEME_HTTP), - &headers); - EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader)); - headers.GetHeader(kChromeProxyHeader, &header_value); - EXPECT_EQ(kExpectedHeader, ParseHeader(header_value)); + + std::string expected_header; + SetHeaderExpectations(kExpectedSession, kExpectedCredentials, kClientStr, + std::string(), std::string(), "low", + std::vector<std::string>(), &expected_header); + + CreateRequestOptions(kBogusVersion); + VerifyExpectedHeader(params()->DefaultOrigin(), expected_header); +} + +TEST_F(DataReductionProxyRequestOptionsTest, ParseExperiments) { + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + data_reduction_proxy::switches::kDataReductionProxyExperiment, + "staging,\"foo,bar\""); + std::vector<std::string> expected_experiments; + expected_experiments.push_back("staging"); + expected_experiments.push_back("\"foo,bar\""); + std::string expected_header; + SetHeaderExpectations(kExpectedSession, kExpectedCredentials, kClientStr, + std::string(), std::string(), std::string(), + expected_experiments, &expected_header); + + CreateRequestOptions(kBogusVersion); + VerifyExpectedHeader(params()->DefaultOrigin(), expected_header); } } // namespace data_reduction_proxy diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc index 8132901..33f7df4 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc @@ -20,6 +20,11 @@ const char kDataReductionProxyAltFallback[] = // The origin of the data reduction proxy dev. const char kDataReductionProxyDev[] = "spdy-proxy-dev-auth-origin"; +// The name of a Data Reduction Proxy experiment to run. These experiments are +// defined by the proxy server. Use --force-fieldtrials for Data Reduction +// Proxy field trials. +const char kDataReductionProxyExperiment[] = "data-reduction-proxy-experiment"; + // The origin of the data reduction proxy fallback. const char kDataReductionProxyFallback[] = "spdy-proxy-auth-fallback"; diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h index d352004..6f682b2 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h @@ -15,6 +15,7 @@ extern const char kDataReductionProxy[]; extern const char kDataReductionProxyAlt[]; extern const char kDataReductionProxyAltFallback[]; extern const char kDataReductionProxyDev[]; +extern const char kDataReductionProxyExperiment[]; extern const char kDataReductionProxyFallback[]; extern const char kDataReductionProxyKey[]; extern const char kDataReductionProxyProbeURL[]; @@ -27,6 +28,7 @@ extern const char kEnableDataReductionProxyAlt[]; extern const char kEnableDataReductionProxyLoFi[]; extern const char kEnableDataReductionProxyBypassWarning[]; + } // namespace switches } // namespace data_reduction_proxy |