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