OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/proxy/mojo_proxy_resolver_impl.h" | 5 #include "net/proxy/mojo_proxy_resolver_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 void TestRequestClient::ResolveDns( | 93 void TestRequestClient::ResolveDns( |
94 std::unique_ptr<HostResolver::RequestInfo> request_info, | 94 std::unique_ptr<HostResolver::RequestInfo> request_info, |
95 interfaces::HostResolverRequestClientPtr client) {} | 95 interfaces::HostResolverRequestClientPtr client) {} |
96 | 96 |
97 void TestRequestClient::OnConnectionError() { | 97 void TestRequestClient::OnConnectionError() { |
98 event_waiter_.NotifyEvent(CONNECTION_ERROR); | 98 event_waiter_.NotifyEvent(CONNECTION_ERROR); |
99 } | 99 } |
100 | 100 |
101 class MockProxyResolverV8Tracing : public ProxyResolverV8Tracing { | 101 class MockProxyResolverV8Tracing : public ProxyResolverV8Tracing { |
102 public: | 102 public: |
103 struct Request { | 103 struct Job { |
104 GURL url; | 104 GURL url; |
105 ProxyInfo* results; | 105 ProxyInfo* results; |
106 CompletionCallback callback; | |
107 bool cancelled = false; | 106 bool cancelled = false; |
| 107 void Complete(int result) { |
| 108 DCHECK(!callback_.is_null()); |
| 109 callback_.Run(result); |
| 110 callback_.Reset(); |
| 111 } |
| 112 |
| 113 bool WasCompleted() { return callback_.is_null(); } |
| 114 |
| 115 void SetCallback(CompletionCallback callback) { callback_ = callback; } |
| 116 |
| 117 private: |
| 118 CompletionCallback callback_; |
108 }; | 119 }; |
| 120 |
| 121 class RequestImpl : public ProxyResolver::Request { |
| 122 public: |
| 123 RequestImpl(Job* job, MockProxyResolverV8Tracing* resolver) |
| 124 : job_(job), resolver_(resolver) {} |
| 125 |
| 126 ~RequestImpl() override { |
| 127 if (job_->WasCompleted()) |
| 128 return; |
| 129 job_->cancelled = true; |
| 130 if (!resolver_->cancel_callback_.is_null()) { |
| 131 resolver_->cancel_callback_.Run(); |
| 132 resolver_->cancel_callback_.Reset(); |
| 133 } |
| 134 } |
| 135 |
| 136 LoadState GetLoadState() override { |
| 137 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; |
| 138 } |
| 139 |
| 140 private: |
| 141 Job* job_; |
| 142 MockProxyResolverV8Tracing* resolver_; |
| 143 }; |
| 144 |
109 MockProxyResolverV8Tracing() {} | 145 MockProxyResolverV8Tracing() {} |
110 | 146 |
111 // ProxyResolverV8Tracing overrides. | 147 // ProxyResolverV8Tracing overrides. |
112 void GetProxyForURL(const GURL& url, | 148 void GetProxyForURL(const GURL& url, |
113 ProxyInfo* results, | 149 ProxyInfo* results, |
114 const CompletionCallback& callback, | 150 const CompletionCallback& callback, |
115 ProxyResolver::RequestHandle* request, | 151 std::unique_ptr<ProxyResolver::Request>* request, |
116 std::unique_ptr<Bindings> bindings) override; | 152 std::unique_ptr<Bindings> bindings) override; |
117 void CancelRequest(ProxyResolver::RequestHandle request_handle) override; | |
118 LoadState GetLoadState(ProxyResolver::RequestHandle request) const override; | |
119 | 153 |
120 // Wait until the mock resolver has received a CancelRequest call. | |
121 void WaitForCancel(); | 154 void WaitForCancel(); |
122 | 155 |
123 const std::vector<Request>& pending_requests() { return pending_requests_; } | 156 const std::vector<std::unique_ptr<Job>>& pending_jobs() { |
| 157 return pending_jobs_; |
| 158 } |
124 | 159 |
125 private: | 160 private: |
126 base::Closure cancel_callback_; | 161 base::Closure cancel_callback_; |
127 std::vector<Request> pending_requests_; | 162 std::vector<std::unique_ptr<Job>> pending_jobs_; |
128 }; | 163 }; |
129 | 164 |
130 void MockProxyResolverV8Tracing::GetProxyForURL( | 165 void MockProxyResolverV8Tracing::GetProxyForURL( |
131 const GURL& url, | 166 const GURL& url, |
132 ProxyInfo* results, | 167 ProxyInfo* results, |
133 const CompletionCallback& callback, | 168 const CompletionCallback& callback, |
134 ProxyResolver::RequestHandle* request, | 169 std::unique_ptr<ProxyResolver::Request>* request, |
135 std::unique_ptr<Bindings> bindings) { | 170 std::unique_ptr<Bindings> bindings) { |
136 pending_requests_.push_back(Request()); | 171 pending_jobs_.push_back(base::WrapUnique(new Job())); |
137 auto& pending_request = pending_requests_.back(); | 172 auto pending_job = pending_jobs_.back().get(); |
138 pending_request.url = url; | 173 pending_job->url = url; |
139 pending_request.results = results; | 174 pending_job->results = results; |
140 pending_request.callback = callback; | 175 pending_job->SetCallback(callback); |
141 *request = | 176 request->reset(new RequestImpl(pending_job, this)); |
142 reinterpret_cast<ProxyResolver::RequestHandle>(pending_requests_.size()); | |
143 } | 177 } |
144 | 178 |
145 void MockProxyResolverV8Tracing::CancelRequest( | |
146 ProxyResolver::RequestHandle request_handle) { | |
147 size_t id = reinterpret_cast<size_t>(request_handle) - 1; | |
148 pending_requests_[id].cancelled = true; | |
149 if (!cancel_callback_.is_null()) { | |
150 cancel_callback_.Run(); | |
151 cancel_callback_.Reset(); | |
152 } | |
153 } | |
154 | |
155 LoadState MockProxyResolverV8Tracing::GetLoadState( | |
156 ProxyResolver::RequestHandle request) const { | |
157 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; | |
158 } | |
159 | 179 |
160 void MockProxyResolverV8Tracing::WaitForCancel() { | 180 void MockProxyResolverV8Tracing::WaitForCancel() { |
161 while (std::find_if(pending_requests_.begin(), pending_requests_.end(), | 181 while (std::find_if(pending_jobs_.begin(), pending_jobs_.end(), |
162 [](const Request& request) { | 182 [](const std::unique_ptr<Job>& job) { |
163 return request.cancelled; | 183 return job->cancelled; |
164 }) != pending_requests_.end()) { | 184 }) != pending_jobs_.end()) { |
165 base::RunLoop run_loop; | 185 base::RunLoop run_loop; |
166 cancel_callback_ = run_loop.QuitClosure(); | 186 cancel_callback_ = run_loop.QuitClosure(); |
167 run_loop.Run(); | 187 run_loop.Run(); |
168 } | 188 } |
169 } | 189 } |
170 | 190 |
171 } // namespace | 191 } // namespace |
172 | 192 |
173 class MojoProxyResolverImplTest : public testing::Test { | 193 class MojoProxyResolverImplTest : public testing::Test { |
174 protected: | 194 protected: |
175 void SetUp() override { | 195 void SetUp() override { |
176 std::unique_ptr<MockProxyResolverV8Tracing> mock_resolver( | 196 std::unique_ptr<MockProxyResolverV8Tracing> mock_resolver( |
177 new MockProxyResolverV8Tracing); | 197 new MockProxyResolverV8Tracing); |
178 mock_proxy_resolver_ = mock_resolver.get(); | 198 mock_proxy_resolver_ = mock_resolver.get(); |
179 resolver_impl_.reset(new MojoProxyResolverImpl(std::move(mock_resolver))); | 199 resolver_impl_.reset(new MojoProxyResolverImpl(std::move(mock_resolver))); |
180 resolver_ = resolver_impl_.get(); | 200 resolver_ = resolver_impl_.get(); |
181 } | 201 } |
182 | 202 |
183 MockProxyResolverV8Tracing* mock_proxy_resolver_; | 203 MockProxyResolverV8Tracing* mock_proxy_resolver_; |
184 | 204 |
185 std::unique_ptr<MojoProxyResolverImpl> resolver_impl_; | 205 std::unique_ptr<MojoProxyResolverImpl> resolver_impl_; |
186 interfaces::ProxyResolver* resolver_; | 206 interfaces::ProxyResolver* resolver_; |
187 }; | 207 }; |
188 | 208 |
189 TEST_F(MojoProxyResolverImplTest, GetProxyForUrl) { | 209 TEST_F(MojoProxyResolverImplTest, GetProxyForUrl) { |
190 interfaces::ProxyResolverRequestClientPtr client_ptr; | 210 interfaces::ProxyResolverRequestClientPtr client_ptr; |
191 TestRequestClient client(mojo::GetProxy(&client_ptr)); | 211 TestRequestClient client(mojo::GetProxy(&client_ptr)); |
192 | 212 |
193 resolver_->GetProxyForUrl(GURL("http://example.com"), std::move(client_ptr)); | 213 resolver_->GetProxyForUrl(GURL(GURL("http://example.com")), |
194 ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size()); | 214 std::move(client_ptr)); |
195 const MockProxyResolverV8Tracing::Request& request = | 215 ASSERT_EQ(1u, mock_proxy_resolver_->pending_jobs().size()); |
196 mock_proxy_resolver_->pending_requests()[0]; | 216 MockProxyResolverV8Tracing::Job* job = |
197 EXPECT_EQ(GURL("http://example.com"), request.url); | 217 mock_proxy_resolver_->pending_jobs()[0].get(); |
| 218 EXPECT_EQ(GURL(GURL("http://example.com")), job->url); |
198 | 219 |
199 request.results->UsePacString( | 220 job->results->UsePacString( |
200 "PROXY proxy.example.com:1; " | 221 "PROXY proxy.example.com:1; " |
201 "SOCKS4 socks4.example.com:2; " | 222 "SOCKS4 socks4.example.com:2; " |
202 "SOCKS5 socks5.example.com:3; " | 223 "SOCKS5 socks5.example.com:3; " |
203 "HTTPS https.example.com:4; " | 224 "HTTPS https.example.com:4; " |
204 "QUIC quic.example.com:65000; " | 225 "QUIC quic.example.com:65000; " |
205 "DIRECT"); | 226 "DIRECT"); |
206 request.callback.Run(OK); | 227 job->Complete(OK); |
207 client.WaitForResult(); | 228 client.WaitForResult(); |
208 | 229 |
209 EXPECT_THAT(client.error(), IsOk()); | 230 EXPECT_THAT(client.error(), IsOk()); |
210 std::vector<ProxyServer> servers = client.results().proxy_list().GetAll(); | 231 std::vector<ProxyServer> servers = client.results().proxy_list().GetAll(); |
211 ASSERT_EQ(6u, servers.size()); | 232 ASSERT_EQ(6u, servers.size()); |
212 EXPECT_EQ(ProxyServer::SCHEME_HTTP, servers[0].scheme()); | 233 EXPECT_EQ(ProxyServer::SCHEME_HTTP, servers[0].scheme()); |
213 EXPECT_EQ("proxy.example.com", servers[0].host_port_pair().host()); | 234 EXPECT_EQ("proxy.example.com", servers[0].host_port_pair().host()); |
214 EXPECT_EQ(1, servers[0].host_port_pair().port()); | 235 EXPECT_EQ(1, servers[0].host_port_pair().port()); |
215 | 236 |
216 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, servers[1].scheme()); | 237 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, servers[1].scheme()); |
(...skipping 13 matching lines...) Expand all Loading... |
230 EXPECT_EQ(65000, servers[4].host_port_pair().port()); | 251 EXPECT_EQ(65000, servers[4].host_port_pair().port()); |
231 | 252 |
232 EXPECT_EQ(ProxyServer::SCHEME_DIRECT, servers[5].scheme()); | 253 EXPECT_EQ(ProxyServer::SCHEME_DIRECT, servers[5].scheme()); |
233 } | 254 } |
234 | 255 |
235 TEST_F(MojoProxyResolverImplTest, GetProxyForUrlFailure) { | 256 TEST_F(MojoProxyResolverImplTest, GetProxyForUrlFailure) { |
236 interfaces::ProxyResolverRequestClientPtr client_ptr; | 257 interfaces::ProxyResolverRequestClientPtr client_ptr; |
237 TestRequestClient client(mojo::GetProxy(&client_ptr)); | 258 TestRequestClient client(mojo::GetProxy(&client_ptr)); |
238 | 259 |
239 resolver_->GetProxyForUrl(GURL("http://example.com"), std::move(client_ptr)); | 260 resolver_->GetProxyForUrl(GURL("http://example.com"), std::move(client_ptr)); |
240 ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size()); | 261 ASSERT_EQ(1u, mock_proxy_resolver_->pending_jobs().size()); |
241 const MockProxyResolverV8Tracing::Request& request = | 262 MockProxyResolverV8Tracing::Job* job = |
242 mock_proxy_resolver_->pending_requests()[0]; | 263 mock_proxy_resolver_->pending_jobs()[0].get(); |
243 EXPECT_EQ(GURL("http://example.com"), request.url); | 264 EXPECT_EQ(GURL(GURL("http://example.com")), job->url); |
244 request.callback.Run(ERR_FAILED); | 265 job->Complete(ERR_FAILED); |
245 client.WaitForResult(); | 266 client.WaitForResult(); |
246 | 267 |
247 EXPECT_THAT(client.error(), IsError(ERR_FAILED)); | 268 EXPECT_THAT(client.error(), IsError(ERR_FAILED)); |
248 std::vector<ProxyServer> proxy_servers = | 269 std::vector<ProxyServer> proxy_servers = |
249 client.results().proxy_list().GetAll(); | 270 client.results().proxy_list().GetAll(); |
250 EXPECT_TRUE(proxy_servers.empty()); | 271 EXPECT_TRUE(proxy_servers.empty()); |
251 } | 272 } |
252 | 273 |
253 TEST_F(MojoProxyResolverImplTest, GetProxyForUrlMultiple) { | 274 TEST_F(MojoProxyResolverImplTest, GetProxyForUrlMultiple) { |
254 interfaces::ProxyResolverRequestClientPtr client_ptr1; | 275 interfaces::ProxyResolverRequestClientPtr client_ptr1; |
255 TestRequestClient client1(mojo::GetProxy(&client_ptr1)); | 276 TestRequestClient client1(mojo::GetProxy(&client_ptr1)); |
256 interfaces::ProxyResolverRequestClientPtr client_ptr2; | 277 interfaces::ProxyResolverRequestClientPtr client_ptr2; |
257 TestRequestClient client2(mojo::GetProxy(&client_ptr2)); | 278 TestRequestClient client2(mojo::GetProxy(&client_ptr2)); |
258 | 279 |
259 resolver_->GetProxyForUrl(GURL("http://example.com"), std::move(client_ptr1)); | 280 resolver_->GetProxyForUrl(GURL("http://example.com"), std::move(client_ptr1)); |
260 resolver_->GetProxyForUrl(GURL("https://example.com"), | 281 resolver_->GetProxyForUrl(GURL("https://example.com"), |
261 std::move(client_ptr2)); | 282 std::move(client_ptr2)); |
262 ASSERT_EQ(2u, mock_proxy_resolver_->pending_requests().size()); | 283 ASSERT_EQ(2u, mock_proxy_resolver_->pending_jobs().size()); |
263 const MockProxyResolverV8Tracing::Request& request1 = | 284 MockProxyResolverV8Tracing::Job* job1 = |
264 mock_proxy_resolver_->pending_requests()[0]; | 285 mock_proxy_resolver_->pending_jobs()[0].get(); |
265 EXPECT_EQ(GURL("http://example.com"), request1.url); | 286 EXPECT_EQ(GURL(GURL("http://example.com")), job1->url); |
266 const MockProxyResolverV8Tracing::Request& request2 = | 287 MockProxyResolverV8Tracing::Job* job2 = |
267 mock_proxy_resolver_->pending_requests()[1]; | 288 mock_proxy_resolver_->pending_jobs()[1].get(); |
268 EXPECT_EQ(GURL("https://example.com"), request2.url); | 289 EXPECT_EQ(GURL("https://example.com"), job2->url); |
269 request1.results->UsePacString("HTTPS proxy.example.com:12345"); | 290 job1->results->UsePacString("HTTPS proxy.example.com:12345"); |
270 request1.callback.Run(OK); | 291 job1->Complete(OK); |
271 request2.results->UsePacString("SOCKS5 another-proxy.example.com:6789"); | 292 job2->results->UsePacString("SOCKS5 another-proxy.example.com:6789"); |
272 request2.callback.Run(OK); | 293 job2->Complete(OK); |
273 client1.WaitForResult(); | 294 client1.WaitForResult(); |
274 client2.WaitForResult(); | 295 client2.WaitForResult(); |
275 | 296 |
276 EXPECT_THAT(client1.error(), IsOk()); | 297 EXPECT_THAT(client1.error(), IsOk()); |
277 std::vector<ProxyServer> proxy_servers1 = | 298 std::vector<ProxyServer> proxy_servers1 = |
278 client1.results().proxy_list().GetAll(); | 299 client1.results().proxy_list().GetAll(); |
279 ASSERT_EQ(1u, proxy_servers1.size()); | 300 ASSERT_EQ(1u, proxy_servers1.size()); |
280 ProxyServer& server1 = proxy_servers1[0]; | 301 ProxyServer& server1 = proxy_servers1[0]; |
281 EXPECT_EQ(ProxyServer::SCHEME_HTTPS, server1.scheme()); | 302 EXPECT_EQ(ProxyServer::SCHEME_HTTPS, server1.scheme()); |
282 EXPECT_EQ("proxy.example.com", server1.host_port_pair().host()); | 303 EXPECT_EQ("proxy.example.com", server1.host_port_pair().host()); |
283 EXPECT_EQ(12345, server1.host_port_pair().port()); | 304 EXPECT_EQ(12345, server1.host_port_pair().port()); |
284 | 305 |
285 EXPECT_THAT(client2.error(), IsOk()); | 306 EXPECT_THAT(client2.error(), IsOk()); |
286 std::vector<ProxyServer> proxy_servers2 = | 307 std::vector<ProxyServer> proxy_servers2 = |
287 client2.results().proxy_list().GetAll(); | 308 client2.results().proxy_list().GetAll(); |
288 ASSERT_EQ(1u, proxy_servers1.size()); | 309 ASSERT_EQ(1u, proxy_servers1.size()); |
289 ProxyServer& server2 = proxy_servers2[0]; | 310 ProxyServer& server2 = proxy_servers2[0]; |
290 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, server2.scheme()); | 311 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, server2.scheme()); |
291 EXPECT_EQ("another-proxy.example.com", server2.host_port_pair().host()); | 312 EXPECT_EQ("another-proxy.example.com", server2.host_port_pair().host()); |
292 EXPECT_EQ(6789, server2.host_port_pair().port()); | 313 EXPECT_EQ(6789, server2.host_port_pair().port()); |
293 } | 314 } |
294 | 315 |
295 TEST_F(MojoProxyResolverImplTest, DestroyClient) { | 316 TEST_F(MojoProxyResolverImplTest, DestroyClient) { |
296 interfaces::ProxyResolverRequestClientPtr client_ptr; | 317 interfaces::ProxyResolverRequestClientPtr client_ptr; |
297 std::unique_ptr<TestRequestClient> client( | 318 std::unique_ptr<TestRequestClient> client( |
298 new TestRequestClient(mojo::GetProxy(&client_ptr))); | 319 new TestRequestClient(mojo::GetProxy(&client_ptr))); |
299 | 320 |
300 resolver_->GetProxyForUrl(GURL("http://example.com"), std::move(client_ptr)); | 321 resolver_->GetProxyForUrl(GURL("http://example.com"), std::move(client_ptr)); |
301 ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size()); | 322 ASSERT_EQ(1u, mock_proxy_resolver_->pending_jobs().size()); |
302 const MockProxyResolverV8Tracing::Request& request = | 323 const MockProxyResolverV8Tracing::Job* job = |
303 mock_proxy_resolver_->pending_requests()[0]; | 324 mock_proxy_resolver_->pending_jobs()[0].get(); |
304 EXPECT_EQ(GURL("http://example.com"), request.url); | 325 EXPECT_EQ(GURL(GURL("http://example.com")), job->url); |
305 request.results->UsePacString("PROXY proxy.example.com:8080"); | 326 job->results->UsePacString("PROXY proxy.example.com:8080"); |
306 client.reset(); | 327 client.reset(); |
307 mock_proxy_resolver_->WaitForCancel(); | 328 mock_proxy_resolver_->WaitForCancel(); |
308 } | 329 } |
309 | 330 |
310 TEST_F(MojoProxyResolverImplTest, DestroyService) { | 331 TEST_F(MojoProxyResolverImplTest, DestroyService) { |
311 interfaces::ProxyResolverRequestClientPtr client_ptr; | 332 interfaces::ProxyResolverRequestClientPtr client_ptr; |
312 TestRequestClient client(mojo::GetProxy(&client_ptr)); | 333 TestRequestClient client(mojo::GetProxy(&client_ptr)); |
313 | 334 |
314 resolver_->GetProxyForUrl(GURL("http://example.com"), std::move(client_ptr)); | 335 resolver_->GetProxyForUrl(GURL("http://example.com"), std::move(client_ptr)); |
315 ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size()); | 336 ASSERT_EQ(1u, mock_proxy_resolver_->pending_jobs().size()); |
316 resolver_impl_.reset(); | 337 resolver_impl_.reset(); |
317 client.event_waiter().WaitForEvent(TestRequestClient::CONNECTION_ERROR); | 338 client.event_waiter().WaitForEvent(TestRequestClient::CONNECTION_ERROR); |
318 } | 339 } |
319 | 340 |
320 } // namespace net | 341 } // namespace net |
OLD | NEW |