• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium OS 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.
4 
5 #include <brillo/http/http_proxy.h>
6 
7 #include <string>
8 #include <vector>
9 
10 #include <base/bind.h>
11 #include <brillo/http/http_transport.h>
12 #include <chromeos/dbus/service_constants.h>
13 #include <dbus/mock_bus.h>
14 #include <dbus/mock_object_proxy.h>
15 #include <gtest/gtest.h>
16 
17 using ::testing::_;
18 using ::testing::ElementsAre;
19 using ::testing::Invoke;
20 using ::testing::Return;
21 
22 namespace {
23 constexpr char kTestUrl[] = "http://www.example.com/test";
24 }  // namespace
25 
26 namespace brillo {
27 namespace http {
28 
29 class HttpProxyTest : public testing::Test {
30  public:
ResolveProxyHandlerAsync(dbus::MethodCall * method_call,int timeout_msec,dbus::ObjectProxy::ResponseCallback callback)31   void ResolveProxyHandlerAsync(dbus::MethodCall* method_call,
32                                 int timeout_msec,
33                                 dbus::ObjectProxy::ResponseCallback callback) {
34     if (null_dbus_response_) {
35       callback.Run(nullptr);
36       return;
37     }
38     callback.Run(CreateDBusResponse(method_call).get());
39   }
40 
ResolveProxyHandler(dbus::MethodCall * method_call,int timeout_msec)41   dbus::Response* ResolveProxyHandler(dbus::MethodCall* method_call,
42                                       int timeout_msec) {
43     if (null_dbus_response_) {
44       return nullptr;
45     }
46     // The mock wraps this back into a std::unique_ptr in the function calling
47     // us.
48     return CreateDBusResponse(method_call).release();
49   }
50 
51   MOCK_METHOD2(GetProxiesCallback, void(bool, const std::vector<std::string>&));
52 
53  protected:
HttpProxyTest()54   HttpProxyTest() {
55     dbus::Bus::Options options;
56     options.bus_type = dbus::Bus::SYSTEM;
57     bus_ = new dbus::MockBus(options);
58     object_proxy_ = new dbus::MockObjectProxy(
59         bus_.get(), chromeos::kNetworkProxyServiceName,
60         dbus::ObjectPath(chromeos::kNetworkProxyServicePath));
61     EXPECT_CALL(*bus_, GetObjectProxy(chromeos::kNetworkProxyServiceName,
62                                       dbus::ObjectPath(
63                                           chromeos::kNetworkProxyServicePath)))
64         .WillOnce(Return(object_proxy_.get()));
65   }
66 
CreateDBusResponse(dbus::MethodCall * method_call)67   std::unique_ptr<dbus::Response> CreateDBusResponse(
68       dbus::MethodCall* method_call) {
69     EXPECT_EQ(method_call->GetInterface(),
70               chromeos::kNetworkProxyServiceInterface);
71     EXPECT_EQ(method_call->GetMember(),
72               chromeos::kNetworkProxyServiceResolveProxyMethod);
73     method_call->SetSerial(1);  // Needs to be non-zero or it fails.
74     std::unique_ptr<dbus::Response> response =
75         dbus::Response::FromMethodCall(method_call);
76     dbus::MessageWriter writer(response.get());
77     writer.AppendString(proxy_info_);
78     if (invalid_dbus_response_) {
79       return response;
80     }
81     writer.AppendString(proxy_err_);
82     return response;
83   }
84 
85   scoped_refptr<dbus::MockBus> bus_;
86   scoped_refptr<dbus::MockObjectProxy> object_proxy_;
87 
88   std::string proxy_info_;
89   std::string proxy_err_;
90   bool null_dbus_response_ = false;
91   bool invalid_dbus_response_ = false;
92 
93  private:
94   DISALLOW_COPY_AND_ASSIGN(HttpProxyTest);
95 };
96 
TEST_F(HttpProxyTest,DBusNullResponseFails)97 TEST_F(HttpProxyTest, DBusNullResponseFails) {
98   std::vector<std::string> proxies;
99   null_dbus_response_ = true;
100   EXPECT_CALL(*object_proxy_, MockCallMethodAndBlock(_, _))
101       .WillOnce(Invoke(this, &HttpProxyTest::ResolveProxyHandler));
102   EXPECT_FALSE(GetChromeProxyServers(bus_, kTestUrl, &proxies));
103 }
104 
TEST_F(HttpProxyTest,DBusInvalidResponseFails)105 TEST_F(HttpProxyTest, DBusInvalidResponseFails) {
106   std::vector<std::string> proxies;
107   invalid_dbus_response_ = true;
108   EXPECT_CALL(*object_proxy_, MockCallMethodAndBlock(_, _))
109       .WillOnce(Invoke(this, &HttpProxyTest::ResolveProxyHandler));
110   EXPECT_FALSE(GetChromeProxyServers(bus_, kTestUrl, &proxies));
111 }
112 
TEST_F(HttpProxyTest,NoProxies)113 TEST_F(HttpProxyTest, NoProxies) {
114   std::vector<std::string> proxies;
115   EXPECT_CALL(*object_proxy_, MockCallMethodAndBlock(_, _))
116       .WillOnce(Invoke(this, &HttpProxyTest::ResolveProxyHandler));
117   EXPECT_TRUE(GetChromeProxyServers(bus_, kTestUrl, &proxies));
118   EXPECT_THAT(proxies, ElementsAre(kDirectProxy));
119 }
120 
TEST_F(HttpProxyTest,MultipleProxiesWithoutDirect)121 TEST_F(HttpProxyTest, MultipleProxiesWithoutDirect) {
122   proxy_info_ = "proxy example.com; socks5 foo.com;";
123   std::vector<std::string> proxies;
124   EXPECT_CALL(*object_proxy_, MockCallMethodAndBlock(_, _))
125       .WillOnce(Invoke(this, &HttpProxyTest::ResolveProxyHandler));
126   EXPECT_TRUE(GetChromeProxyServers(bus_, kTestUrl, &proxies));
127   EXPECT_THAT(proxies, ElementsAre("http://example.com", "socks5://foo.com",
128                                    kDirectProxy));
129 }
130 
TEST_F(HttpProxyTest,MultipleProxiesWithDirect)131 TEST_F(HttpProxyTest, MultipleProxiesWithDirect) {
132   proxy_info_ = "socks foo.com; Https example.com ; badproxy example2.com ; "
133                 "socks5 test.com  ; proxy foobar.com; DIRECT ";
134   std::vector<std::string> proxies;
135   EXPECT_CALL(*object_proxy_, MockCallMethodAndBlock(_, _))
136       .WillOnce(Invoke(this, &HttpProxyTest::ResolveProxyHandler));
137   EXPECT_TRUE(GetChromeProxyServers(bus_, kTestUrl, &proxies));
138   EXPECT_THAT(proxies, ElementsAre("socks4://foo.com", "https://example.com",
139                                    "socks5://test.com", "http://foobar.com",
140                                    kDirectProxy));
141 }
142 
TEST_F(HttpProxyTest,DBusNullResponseFailsAsync)143 TEST_F(HttpProxyTest, DBusNullResponseFailsAsync) {
144   null_dbus_response_ = true;
145   EXPECT_CALL(*object_proxy_, CallMethod(_, _, _))
146       .WillOnce(Invoke(this, &HttpProxyTest::ResolveProxyHandlerAsync));
147   EXPECT_CALL(*this, GetProxiesCallback(false, _));
148   GetChromeProxyServersAsync(
149       bus_, kTestUrl,
150       base::Bind(&HttpProxyTest::GetProxiesCallback, base::Unretained(this)));
151 }
152 
TEST_F(HttpProxyTest,DBusInvalidResponseFailsAsync)153 TEST_F(HttpProxyTest, DBusInvalidResponseFailsAsync) {
154   invalid_dbus_response_ = true;
155   EXPECT_CALL(*object_proxy_, CallMethod(_, _, _))
156       .WillOnce(Invoke(this, &HttpProxyTest::ResolveProxyHandlerAsync));
157   EXPECT_CALL(*this, GetProxiesCallback(false, _));
158   GetChromeProxyServersAsync(
159       bus_, kTestUrl,
160       base::Bind(&HttpProxyTest::GetProxiesCallback, base::Unretained(this)));
161 }
162 
163 // We don't need to test all the proxy cases with async because that will be
164 // using the same internal parsing code.
TEST_F(HttpProxyTest,MultipleProxiesWithDirectAsync)165 TEST_F(HttpProxyTest, MultipleProxiesWithDirectAsync) {
166   proxy_info_ = "socks foo.com; Https example.com ; badproxy example2.com ; "
167                 "socks5 test.com  ; proxy foobar.com; DIRECT ";
168   std::vector<std::string> expected = {
169       "socks4://foo.com", "https://example.com", "socks5://test.com",
170       "http://foobar.com", kDirectProxy};
171   EXPECT_CALL(*object_proxy_, CallMethod(_, _, _))
172       .WillOnce(Invoke(this, &HttpProxyTest::ResolveProxyHandlerAsync));
173   EXPECT_CALL(*this, GetProxiesCallback(true, expected));
174   GetChromeProxyServersAsync(
175       bus_, kTestUrl,
176       base::Bind(&HttpProxyTest::GetProxiesCallback, base::Unretained(this)));
177 }
178 
179 }  // namespace http
180 }  // namespace brillo
181