1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "components/data_reduction_proxy/browser/data_reduction_proxy_params_test_utils.h"
15 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h"
16 #include "net/base/auth.h"
17 #include "net/base/host_port_pair.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
23 const char kChromeProxyHeader[] = "chrome-proxy";
24 const char kOtherProxy[] = "testproxy:17";
27 #if defined(OS_ANDROID)
28 const char kClient[] = "android";
30 const char kClient[] = "ios";
32 const char kClient[] = "";
34 const char kVersion[] = "0";
35 const char kTestKey[] = "test-key";
36 const char kExpectedCredentials[] = "96bd72ec4a050ba60981743d41787768";
37 const char kExpectedSession[] = "0-1633771873-1633771873-1633771873";
39 const char kTestKey2[] = "test-key2";
40 const char kExpectedCredentials2[] = "c911fdb402f578787562cf7f00eda972";
41 const char kExpectedSession2[] = "0-1633771873-1633771873-1633771873";
42 #if defined(OS_ANDROID)
43 const char kExpectedHeader2[] =
44 "ps=0-1633771873-1633771873-1633771873, "
45 "sid=c911fdb402f578787562cf7f00eda972, v=0, c=android";
46 const char kExpectedHeader3[] =
47 "ps=86401-1633771873-1633771873-1633771873, "
48 "sid=d7c1c34ef6b90303b01c48a6c1db6419, v=0, c=android";
50 const char kExpectedHeader2[] =
51 "ps=0-1633771873-1633771873-1633771873, "
52 "sid=c911fdb402f578787562cf7f00eda972, v=0, c=ios";
53 const char kExpectedHeader3[] =
54 "ps=86401-1633771873-1633771873-1633771873, "
55 "sid=d7c1c34ef6b90303b01c48a6c1db6419, v=0, c=ios";
57 const char kExpectedHeader2[] =
58 "ps=0-1633771873-1633771873-1633771873, "
59 "sid=c911fdb402f578787562cf7f00eda972, v=0";
60 const char kExpectedHeader3[] =
61 "ps=86401-1633771873-1633771873-1633771873, "
62 "sid=d7c1c34ef6b90303b01c48a6c1db6419, v=0";
65 const char kDataReductionProxyKey[] = "12345";
69 namespace data_reduction_proxy {
71 class TestDataReductionProxyAuthRequestHandler
72 : public DataReductionProxyAuthRequestHandler {
74 TestDataReductionProxyAuthRequestHandler(
75 const std::string& client,
76 const std::string& version,
77 DataReductionProxyParams* params,
78 base::MessageLoopProxy* loop_proxy)
79 : DataReductionProxyAuthRequestHandler(
80 client, version, params, loop_proxy) {}
82 virtual std::string GetDefaultKey() const OVERRIDE {
86 virtual base::Time Now() const OVERRIDE {
87 return base::Time::UnixEpoch() + now_offset_;
90 virtual void RandBytes(void* output, size_t length) OVERRIDE {
91 char* c = static_cast<char*>(output);
92 for (size_t i = 0; i < length; ++i) {
97 // Time after the unix epoch that Now() reports.
98 void set_offset(const base::TimeDelta& now_offset) {
99 now_offset_ = now_offset;
103 base::TimeDelta now_offset_;
108 class DataReductionProxyAuthRequestHandlerTest : public testing::Test {
110 DataReductionProxyAuthRequestHandlerTest()
111 : loop_proxy_(base::MessageLoopProxy::current().get()) {
113 // Required for MessageLoopProxy::current().
114 base::MessageLoopForUI loop_;
115 base::MessageLoopProxy* loop_proxy_;
118 TEST_F(DataReductionProxyAuthRequestHandlerTest, Authorization) {
119 scoped_ptr<TestDataReductionProxyParams> params;
121 new TestDataReductionProxyParams(
122 DataReductionProxyParams::kAllowed |
123 DataReductionProxyParams::kFallbackAllowed |
124 DataReductionProxyParams::kPromoAllowed,
125 TestDataReductionProxyParams::HAS_EVERYTHING &
126 ~TestDataReductionProxyParams::HAS_DEV_ORIGIN));
127 TestDataReductionProxyAuthRequestHandler auth_handler(kClient,
132 base::RunLoop().RunUntilIdle();
133 EXPECT_EQ(auth_handler.client_, kClient);
134 EXPECT_EQ(kVersion, auth_handler.version_);
135 EXPECT_EQ(auth_handler.key_, kTestKey);
136 EXPECT_EQ(kExpectedCredentials, auth_handler.credentials_);
137 EXPECT_EQ(kExpectedSession, auth_handler.session_);
140 auth_handler.SetKeyOnUI(kTestKey2);
141 base::RunLoop().RunUntilIdle();
142 EXPECT_EQ(kTestKey2, auth_handler.key_);
143 EXPECT_EQ(kExpectedCredentials2, auth_handler.credentials_);
144 EXPECT_EQ(kExpectedSession2, auth_handler.session_);
147 // Don't write headers if the proxy is invalid.
148 net::HttpRequestHeaders headers;
149 auth_handler.MaybeAddRequestHeader(NULL, net::ProxyServer(), &headers);
150 EXPECT_FALSE(headers.HasHeader(kChromeProxyHeader));
152 // Don't write headers with a valid proxy, that's not a data reduction proxy.
153 auth_handler.MaybeAddRequestHeader(
155 net::ProxyServer::FromURI(kOtherProxy, net::ProxyServer::SCHEME_HTTP),
157 EXPECT_FALSE(headers.HasHeader(kChromeProxyHeader));
159 // Write headers with a valid data reduction proxy;
160 auth_handler.MaybeAddRequestHeader(
162 net::ProxyServer::FromURI(
163 net::HostPortPair::FromURL(GURL(params->DefaultOrigin())).ToString(),
164 net::ProxyServer::SCHEME_HTTP),
166 EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader));
167 std::string header_value;
168 headers.GetHeader(kChromeProxyHeader, &header_value);
169 EXPECT_EQ(kExpectedHeader2, header_value);
171 // Fast forward 24 hours. The header should be the same.
172 auth_handler.set_offset(base::TimeDelta::FromSeconds(24 * 60 * 60));
173 net::HttpRequestHeaders headers2;
174 // Write headers with a valid data reduction proxy;
175 auth_handler.MaybeAddRequestHeader(
177 net::ProxyServer::FromURI(
178 net::HostPortPair::FromURL(GURL(params->DefaultOrigin())).ToString(),
179 net::ProxyServer::SCHEME_HTTP),
181 EXPECT_TRUE(headers2.HasHeader(kChromeProxyHeader));
182 std::string header_value2;
183 headers2.GetHeader(kChromeProxyHeader, &header_value2);
184 EXPECT_EQ(kExpectedHeader2, header_value2);
186 // Fast forward one more second. The header should be new.
187 auth_handler.set_offset(base::TimeDelta::FromSeconds(24 * 60 * 60 + 1));
188 net::HttpRequestHeaders headers3;
189 // Write headers with a valid data reduction proxy;
190 auth_handler.MaybeAddRequestHeader(
192 net::ProxyServer::FromURI(
193 net::HostPortPair::FromURL(GURL(params->DefaultOrigin())).ToString(),
194 net::ProxyServer::SCHEME_HTTP),
196 EXPECT_TRUE(headers3.HasHeader(kChromeProxyHeader));
197 std::string header_value3;
198 headers3.GetHeader(kChromeProxyHeader, &header_value3);
199 EXPECT_EQ(kExpectedHeader3, header_value3);
202 TEST_F(DataReductionProxyAuthRequestHandlerTest, AuthHashForSalt) {
203 std::string salt = "8675309"; // Jenny's number to test the hash generator.
204 std::string salted_key = salt + kDataReductionProxyKey + salt;
205 base::string16 expected_hash = base::UTF8ToUTF16(base::MD5String(salted_key));
206 EXPECT_EQ(expected_hash,
207 DataReductionProxyAuthRequestHandler::AuthHashForSalt(
208 8675309, kDataReductionProxyKey));
211 } // namespace data_reduction_proxy