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