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