| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 #ifndef NET_PROXY_MOCK_PROXY_RESOLVER_H_ |
| 6 #define NET_PROXY_MOCK_PROXY_RESOLVER_H_ |
| 7 |
| 5 #include <vector> | 8 #include <vector> |
| 6 | 9 |
| 7 #include "base/logging.h" | 10 #include "base/logging.h" |
| 8 #include "base/string_util.h" | |
| 9 #include "googleurl/src/gurl.h" | 11 #include "googleurl/src/gurl.h" |
| 10 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
| 11 #include "net/base/test_completion_callback.h" | |
| 12 #include "net/proxy/proxy_config_service.h" | |
| 13 #include "net/proxy/proxy_resolver.h" | 13 #include "net/proxy/proxy_resolver.h" |
| 14 #include "net/proxy/proxy_script_fetcher.h" | |
| 15 #include "net/proxy/proxy_service.h" | |
| 16 #include "testing/gtest/include/gtest/gtest.h" | |
| 17 | 14 |
| 18 // TODO(eroman): Write a test which exercises | |
| 19 // ProxyService::SuspendAllPendingRequests(). | |
| 20 namespace net { | 15 namespace net { |
| 21 namespace { | |
| 22 | |
| 23 class MockProxyConfigService: public ProxyConfigService { | |
| 24 public: | |
| 25 MockProxyConfigService() {} // Direct connect. | |
| 26 explicit MockProxyConfigService(const ProxyConfig& pc) : config(pc) {} | |
| 27 explicit MockProxyConfigService(const std::string& pac_url) { | |
| 28 config.pac_url = GURL(pac_url); | |
| 29 } | |
| 30 | |
| 31 virtual int GetProxyConfig(ProxyConfig* results) { | |
| 32 *results = config; | |
| 33 return OK; | |
| 34 } | |
| 35 | |
| 36 ProxyConfig config; | |
| 37 }; | |
| 38 | 16 |
| 39 // Asynchronous mock proxy resolver. All requests complete asynchronously, | 17 // Asynchronous mock proxy resolver. All requests complete asynchronously, |
| 40 // user must call Request::CompleteNow() on a pending request to signal it. | 18 // user must call Request::CompleteNow() on a pending request to signal it. |
| 41 class MockAsyncProxyResolverBase : public ProxyResolver { | 19 class MockAsyncProxyResolverBase : public ProxyResolver { |
| 42 public: | 20 public: |
| 43 class Request : public base::RefCounted<Request> { | 21 class Request : public base::RefCounted<Request> { |
| 44 public: | 22 public: |
| 45 Request(MockAsyncProxyResolverBase* resolver, | 23 Request(MockAsyncProxyResolverBase* resolver, |
| 46 const GURL& url, | 24 const GURL& url, |
| 47 ProxyInfo* results, | 25 ProxyInfo* results, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 | 104 |
| 127 virtual void CancelRequest(RequestHandle request_handle) { | 105 virtual void CancelRequest(RequestHandle request_handle) { |
| 128 scoped_refptr<Request> request = reinterpret_cast<Request*>(request_handle); | 106 scoped_refptr<Request> request = reinterpret_cast<Request*>(request_handle); |
| 129 cancelled_requests_.push_back(request); | 107 cancelled_requests_.push_back(request); |
| 130 RemovePendingRequest(request); | 108 RemovePendingRequest(request); |
| 131 } | 109 } |
| 132 | 110 |
| 133 virtual int SetPacScript(const GURL& pac_url, | 111 virtual int SetPacScript(const GURL& pac_url, |
| 134 const std::string& pac_bytes, | 112 const std::string& pac_bytes, |
| 135 CompletionCallback* callback) { | 113 CompletionCallback* callback) { |
| 136 EXPECT_EQ(NULL, pending_set_pac_script_request_.get()); | 114 DCHECK(!pending_set_pac_script_request_.get()); |
| 137 pending_set_pac_script_request_.reset( | 115 pending_set_pac_script_request_.reset( |
| 138 new SetPacScriptRequest(this, pac_url, pac_bytes, callback)); | 116 new SetPacScriptRequest(this, pac_url, pac_bytes, callback)); |
| 139 // Finished when user calls SetPacScriptRequest::CompleteNow(). | 117 // Finished when user calls SetPacScriptRequest::CompleteNow(). |
| 140 return ERR_IO_PENDING; | 118 return ERR_IO_PENDING; |
| 141 } | 119 } |
| 142 | 120 |
| 143 const RequestsList& pending_requests() const { | 121 const RequestsList& pending_requests() const { |
| 144 return pending_requests_; | 122 return pending_requests_; |
| 145 } | 123 } |
| 146 | 124 |
| 147 const RequestsList& cancelled_requests() const { | 125 const RequestsList& cancelled_requests() const { |
| 148 return cancelled_requests_; | 126 return cancelled_requests_; |
| 149 } | 127 } |
| 150 | 128 |
| 151 SetPacScriptRequest* pending_set_pac_script_request() const { | 129 SetPacScriptRequest* pending_set_pac_script_request() const { |
| 152 return pending_set_pac_script_request_.get(); | 130 return pending_set_pac_script_request_.get(); |
| 153 } | 131 } |
| 154 | 132 |
| 155 void RemovePendingRequest(Request* request) { | 133 void RemovePendingRequest(Request* request) { |
| 156 RequestsList::iterator it = std::find( | 134 RequestsList::iterator it = std::find( |
| 157 pending_requests_.begin(), pending_requests_.end(), request); | 135 pending_requests_.begin(), pending_requests_.end(), request); |
| 158 DCHECK(it != pending_requests_.end()); | 136 DCHECK(it != pending_requests_.end()); |
| 159 pending_requests_.erase(it); | 137 pending_requests_.erase(it); |
| 160 } | 138 } |
| 161 | 139 |
| 162 void RemovePendingSetPacScriptRequest(SetPacScriptRequest* request) { | 140 void RemovePendingSetPacScriptRequest(SetPacScriptRequest* request) { |
| 163 EXPECT_EQ(request, pending_set_pac_script_request()); | 141 DCHECK_EQ(request, pending_set_pac_script_request()); |
| 164 pending_set_pac_script_request_.reset(); | 142 pending_set_pac_script_request_.reset(); |
| 165 } | 143 } |
| 166 | 144 |
| 167 protected: | 145 protected: |
| 168 explicit MockAsyncProxyResolverBase(bool expects_pac_bytes) | 146 explicit MockAsyncProxyResolverBase(bool expects_pac_bytes) |
| 169 : ProxyResolver(expects_pac_bytes) {} | 147 : ProxyResolver(expects_pac_bytes) {} |
| 170 | 148 |
| 171 private: | 149 private: |
| 172 RequestsList pending_requests_; | 150 RequestsList pending_requests_; |
| 173 RequestsList cancelled_requests_; | 151 RequestsList cancelled_requests_; |
| 174 scoped_ptr<SetPacScriptRequest> pending_set_pac_script_request_; | 152 scoped_ptr<SetPacScriptRequest> pending_set_pac_script_request_; |
| 175 }; | 153 }; |
| 176 | 154 |
| 177 class MockAsyncProxyResolver : public MockAsyncProxyResolverBase { | 155 class MockAsyncProxyResolver : public MockAsyncProxyResolverBase { |
| 178 public: | 156 public: |
| 179 MockAsyncProxyResolver() | 157 MockAsyncProxyResolver() |
| 180 : MockAsyncProxyResolverBase(false /*expects_pac_bytes*/) {} | 158 : MockAsyncProxyResolverBase(false /*expects_pac_bytes*/) {} |
| 181 }; | 159 }; |
| 182 | 160 |
| 183 class MockAsyncProxyResolverExpectsBytes : public MockAsyncProxyResolverBase { | 161 class MockAsyncProxyResolverExpectsBytes : public MockAsyncProxyResolverBase { |
| 184 public: | 162 public: |
| 185 MockAsyncProxyResolverExpectsBytes() | 163 MockAsyncProxyResolverExpectsBytes() |
| 186 : MockAsyncProxyResolverBase(true /*expects_pac_bytes*/) {} | 164 : MockAsyncProxyResolverBase(true /*expects_pac_bytes*/) {} |
| 187 }; | 165 }; |
| 188 | 166 |
| 189 } // namespace | 167 } // namespace net |
| 190 | 168 |
| 191 // A mock ProxyScriptFetcher. No result will be returned to the fetch client | 169 #endif // NET_PROXY_MOCK_PROXY_RESOLVER_H_ |
| 192 // until we call NotifyFetchCompletion() to set the results. | |
| 193 class MockProxyScriptFetcher : public ProxyScriptFetcher { | |
| 194 public: | |
| 195 MockProxyScriptFetcher() | |
| 196 : pending_request_callback_(NULL), pending_request_bytes_(NULL) { | |
| 197 } | |
| 198 | |
| 199 // ProxyScriptFetcher implementation. | |
| 200 virtual int Fetch(const GURL& url, | |
| 201 std::string* bytes, | |
| 202 CompletionCallback* callback) { | |
| 203 DCHECK(!has_pending_request()); | |
| 204 | |
| 205 // Save the caller's information, and have them wait. | |
| 206 pending_request_url_ = url; | |
| 207 pending_request_callback_ = callback; | |
| 208 pending_request_bytes_ = bytes; | |
| 209 return ERR_IO_PENDING; | |
| 210 } | |
| 211 | |
| 212 void NotifyFetchCompletion(int result, const std::string& bytes) { | |
| 213 DCHECK(has_pending_request()); | |
| 214 *pending_request_bytes_ = bytes; | |
| 215 CompletionCallback* callback = pending_request_callback_; | |
| 216 pending_request_callback_ = NULL; | |
| 217 callback->Run(result); | |
| 218 } | |
| 219 | |
| 220 virtual void Cancel() {} | |
| 221 | |
| 222 const GURL& pending_request_url() const { | |
| 223 return pending_request_url_; | |
| 224 } | |
| 225 | |
| 226 bool has_pending_request() const { | |
| 227 return pending_request_callback_ != NULL; | |
| 228 } | |
| 229 | |
| 230 private: | |
| 231 GURL pending_request_url_; | |
| 232 CompletionCallback* pending_request_callback_; | |
| 233 std::string* pending_request_bytes_; | |
| 234 }; | |
| 235 | |
| 236 TEST(ProxyServiceTest, Direct) { | |
| 237 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; | |
| 238 ProxyService service(new MockProxyConfigService, resolver); | |
| 239 | |
| 240 GURL url("http://www.google.com/"); | |
| 241 | |
| 242 ProxyInfo info; | |
| 243 TestCompletionCallback callback; | |
| 244 int rv = service.ResolveProxy(url, &info, &callback, NULL); | |
| 245 EXPECT_EQ(OK, rv); | |
| 246 EXPECT_TRUE(resolver->pending_requests().empty()); | |
| 247 | |
| 248 EXPECT_TRUE(info.is_direct()); | |
| 249 } | |
| 250 | |
| 251 TEST(ProxyServiceTest, PAC) { | |
| 252 MockProxyConfigService* config_service = | |
| 253 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 254 | |
| 255 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; | |
| 256 | |
| 257 ProxyService service(config_service, resolver); | |
| 258 | |
| 259 GURL url("http://www.google.com/"); | |
| 260 | |
| 261 ProxyInfo info; | |
| 262 TestCompletionCallback callback; | |
| 263 int rv = service.ResolveProxy(url, &info, &callback, NULL); | |
| 264 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 265 | |
| 266 EXPECT_EQ(GURL("http://foopy/proxy.pac"), | |
| 267 resolver->pending_set_pac_script_request()->pac_url()); | |
| 268 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 269 | |
| 270 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 271 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 272 | |
| 273 // Set the result in proxy resolver. | |
| 274 resolver->pending_requests()[0]->results()->UseNamedProxy("foopy"); | |
| 275 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 276 | |
| 277 EXPECT_EQ(OK, callback.WaitForResult()); | |
| 278 EXPECT_FALSE(info.is_direct()); | |
| 279 EXPECT_EQ("foopy:80", info.proxy_server().ToURI()); | |
| 280 } | |
| 281 | |
| 282 // Test that the proxy resolver does not see the URL's username/password | |
| 283 // or its reference section. | |
| 284 TEST(ProxyServiceTest, PAC_NoIdentityOrHash) { | |
| 285 MockProxyConfigService* config_service = | |
| 286 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 287 | |
| 288 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; | |
| 289 | |
| 290 ProxyService service(config_service, resolver); | |
| 291 | |
| 292 GURL url("http://username:password@www.google.com/?ref#hash#hash"); | |
| 293 | |
| 294 ProxyInfo info; | |
| 295 TestCompletionCallback callback; | |
| 296 int rv = service.ResolveProxy(url, &info, &callback, NULL); | |
| 297 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 298 | |
| 299 EXPECT_EQ(GURL("http://foopy/proxy.pac"), | |
| 300 resolver->pending_set_pac_script_request()->pac_url()); | |
| 301 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 302 | |
| 303 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 304 // The URL should have been simplified, stripping the username/password/hash. | |
| 305 EXPECT_EQ(GURL("http://www.google.com/?ref"), | |
| 306 resolver->pending_requests()[0]->url()); | |
| 307 | |
| 308 // We end here without ever completing the request -- destruction of | |
| 309 // ProxyService will cancel the outstanding request. | |
| 310 } | |
| 311 | |
| 312 TEST(ProxyServiceTest, PAC_FailoverToDirect) { | |
| 313 MockProxyConfigService* config_service = | |
| 314 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 315 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; | |
| 316 | |
| 317 ProxyService service(config_service, resolver); | |
| 318 | |
| 319 GURL url("http://www.google.com/"); | |
| 320 | |
| 321 ProxyInfo info; | |
| 322 TestCompletionCallback callback1; | |
| 323 int rv = service.ResolveProxy(url, &info, &callback1, NULL); | |
| 324 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 325 | |
| 326 EXPECT_EQ(GURL("http://foopy/proxy.pac"), | |
| 327 resolver->pending_set_pac_script_request()->pac_url()); | |
| 328 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 329 | |
| 330 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 331 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 332 | |
| 333 // Set the result in proxy resolver. | |
| 334 resolver->pending_requests()[0]->results()->UseNamedProxy("foopy:8080"); | |
| 335 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 336 | |
| 337 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 338 EXPECT_FALSE(info.is_direct()); | |
| 339 EXPECT_EQ("foopy:8080", info.proxy_server().ToURI()); | |
| 340 | |
| 341 // Now, imagine that connecting to foopy:8080 fails. | |
| 342 TestCompletionCallback callback2; | |
| 343 rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); | |
| 344 EXPECT_EQ(OK, rv); | |
| 345 EXPECT_TRUE(info.is_direct()); | |
| 346 } | |
| 347 | |
| 348 TEST(ProxyServiceTest, ProxyResolverFails) { | |
| 349 // Test what happens when the ProxyResolver fails (this could represent | |
| 350 // a failure to download the PAC script in the case of ProxyResolvers which | |
| 351 // do the fetch internally.) | |
| 352 // TODO(eroman): change this comment. | |
| 353 | |
| 354 MockProxyConfigService* config_service = | |
| 355 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 356 | |
| 357 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; | |
| 358 | |
| 359 ProxyService service(config_service, resolver); | |
| 360 | |
| 361 // Start first resolve request. | |
| 362 GURL url("http://www.google.com/"); | |
| 363 ProxyInfo info; | |
| 364 TestCompletionCallback callback1; | |
| 365 int rv = service.ResolveProxy(url, &info, &callback1, NULL); | |
| 366 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 367 | |
| 368 EXPECT_EQ(GURL("http://foopy/proxy.pac"), | |
| 369 resolver->pending_set_pac_script_request()->pac_url()); | |
| 370 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 371 | |
| 372 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 373 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 374 | |
| 375 // Fail the first resolve request in MockAsyncProxyResolver. | |
| 376 resolver->pending_requests()[0]->CompleteNow(ERR_FAILED); | |
| 377 | |
| 378 EXPECT_EQ(ERR_FAILED, callback1.WaitForResult()); | |
| 379 | |
| 380 // The second resolve request will automatically select direct connect, | |
| 381 // because it has cached the configuration as being bad. | |
| 382 TestCompletionCallback callback2; | |
| 383 rv = service.ResolveProxy(url, &info, &callback2, NULL); | |
| 384 EXPECT_EQ(OK, rv); | |
| 385 EXPECT_TRUE(info.is_direct()); | |
| 386 EXPECT_TRUE(resolver->pending_requests().empty()); | |
| 387 | |
| 388 // But, if that fails, then we should give the proxy config another shot | |
| 389 // since we have never tried it with this URL before. | |
| 390 TestCompletionCallback callback3; | |
| 391 rv = service.ReconsiderProxyAfterError(url, &info, &callback3, NULL); | |
| 392 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 393 | |
| 394 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 395 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 396 | |
| 397 // Set the result in proxy resolver. | |
| 398 resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080"); | |
| 399 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 400 | |
| 401 EXPECT_EQ(OK, callback3.WaitForResult()); | |
| 402 EXPECT_FALSE(info.is_direct()); | |
| 403 EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI()); | |
| 404 } | |
| 405 | |
| 406 TEST(ProxyServiceTest, ProxyFallback) { | |
| 407 // Test what happens when we specify multiple proxy servers and some of them | |
| 408 // are bad. | |
| 409 | |
| 410 MockProxyConfigService* config_service = | |
| 411 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 412 | |
| 413 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; | |
| 414 | |
| 415 ProxyService service(config_service, resolver); | |
| 416 | |
| 417 GURL url("http://www.google.com/"); | |
| 418 | |
| 419 // Get the proxy information. | |
| 420 ProxyInfo info; | |
| 421 TestCompletionCallback callback1; | |
| 422 int rv = service.ResolveProxy(url, &info, &callback1, NULL); | |
| 423 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 424 | |
| 425 EXPECT_EQ(GURL("http://foopy/proxy.pac"), | |
| 426 resolver->pending_set_pac_script_request()->pac_url()); | |
| 427 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 428 | |
| 429 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 430 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 431 | |
| 432 // Set the result in proxy resolver. | |
| 433 resolver->pending_requests()[0]->results()->UseNamedProxy( | |
| 434 "foopy1:8080;foopy2:9090"); | |
| 435 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 436 | |
| 437 // The first item is valid. | |
| 438 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 439 EXPECT_FALSE(info.is_direct()); | |
| 440 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); | |
| 441 | |
| 442 // Fake an error on the proxy. | |
| 443 TestCompletionCallback callback2; | |
| 444 rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); | |
| 445 EXPECT_EQ(OK, rv); | |
| 446 | |
| 447 // The second proxy should be specified. | |
| 448 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); | |
| 449 | |
| 450 TestCompletionCallback callback3; | |
| 451 rv = service.ResolveProxy(url, &info, &callback3, NULL); | |
| 452 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 453 | |
| 454 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 455 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 456 | |
| 457 // Set the result in proxy resolver -- the second result is already known | |
| 458 // to be bad. | |
| 459 resolver->pending_requests()[0]->results()->UseNamedProxy( | |
| 460 "foopy3:7070;foopy1:8080;foopy2:9090"); | |
| 461 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 462 | |
| 463 EXPECT_EQ(OK, callback3.WaitForResult()); | |
| 464 EXPECT_FALSE(info.is_direct()); | |
| 465 EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI()); | |
| 466 | |
| 467 // We fake another error. It should now try the third one. | |
| 468 TestCompletionCallback callback4; | |
| 469 rv = service.ReconsiderProxyAfterError(url, &info, &callback4, NULL); | |
| 470 EXPECT_EQ(OK, rv); | |
| 471 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); | |
| 472 | |
| 473 // Fake another error, the last proxy is gone, the list should now be empty. | |
| 474 TestCompletionCallback callback5; | |
| 475 rv = service.ReconsiderProxyAfterError(url, &info, &callback5, NULL); | |
| 476 EXPECT_EQ(OK, rv); // We try direct. | |
| 477 EXPECT_TRUE(info.is_direct()); | |
| 478 | |
| 479 // If it fails again, we don't have anything else to try. | |
| 480 TestCompletionCallback callback6; | |
| 481 rv = service.ReconsiderProxyAfterError(url, &info, &callback6, NULL); | |
| 482 EXPECT_EQ(ERR_FAILED, rv); | |
| 483 | |
| 484 // TODO(nsylvain): Test that the proxy can be retried after the delay. | |
| 485 } | |
| 486 | |
| 487 TEST(ProxyServiceTest, ProxyFallback_NewSettings) { | |
| 488 // Test proxy failover when new settings are available. | |
| 489 | |
| 490 MockProxyConfigService* config_service = | |
| 491 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 492 | |
| 493 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; | |
| 494 | |
| 495 ProxyService service(config_service, resolver); | |
| 496 | |
| 497 GURL url("http://www.google.com/"); | |
| 498 | |
| 499 // Get the proxy information. | |
| 500 ProxyInfo info; | |
| 501 TestCompletionCallback callback1; | |
| 502 int rv = service.ResolveProxy(url, &info, &callback1, NULL); | |
| 503 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 504 | |
| 505 EXPECT_EQ(GURL("http://foopy/proxy.pac"), | |
| 506 resolver->pending_set_pac_script_request()->pac_url()); | |
| 507 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 508 | |
| 509 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 510 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 511 | |
| 512 // Set the result in proxy resolver. | |
| 513 resolver->pending_requests()[0]->results()->UseNamedProxy( | |
| 514 "foopy1:8080;foopy2:9090"); | |
| 515 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 516 | |
| 517 // The first item is valid. | |
| 518 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 519 EXPECT_FALSE(info.is_direct()); | |
| 520 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); | |
| 521 | |
| 522 // Fake an error on the proxy, and also a new configuration on the proxy. | |
| 523 config_service->config = ProxyConfig(); | |
| 524 config_service->config.pac_url = GURL("http://foopy-new/proxy.pac"); | |
| 525 | |
| 526 TestCompletionCallback callback2; | |
| 527 rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); | |
| 528 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 529 | |
| 530 EXPECT_EQ(GURL("http://foopy-new/proxy.pac"), | |
| 531 resolver->pending_set_pac_script_request()->pac_url()); | |
| 532 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 533 | |
| 534 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 535 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 536 | |
| 537 resolver->pending_requests()[0]->results()->UseNamedProxy( | |
| 538 "foopy1:8080;foopy2:9090"); | |
| 539 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 540 | |
| 541 // The first proxy is still there since the configuration changed. | |
| 542 EXPECT_EQ(OK, callback2.WaitForResult()); | |
| 543 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); | |
| 544 | |
| 545 // We fake another error. It should now ignore the first one. | |
| 546 TestCompletionCallback callback3; | |
| 547 rv = service.ReconsiderProxyAfterError(url, &info, &callback3, NULL); | |
| 548 EXPECT_EQ(OK, rv); | |
| 549 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); | |
| 550 | |
| 551 // We simulate a new configuration. | |
| 552 config_service->config = ProxyConfig(); | |
| 553 config_service->config.pac_url = GURL("http://foopy-new2/proxy.pac"); | |
| 554 | |
| 555 // We fake another error. It should go back to the first proxy. | |
| 556 TestCompletionCallback callback4; | |
| 557 rv = service.ReconsiderProxyAfterError(url, &info, &callback4, NULL); | |
| 558 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 559 | |
| 560 EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"), | |
| 561 resolver->pending_set_pac_script_request()->pac_url()); | |
| 562 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 563 | |
| 564 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 565 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 566 | |
| 567 resolver->pending_requests()[0]->results()->UseNamedProxy( | |
| 568 "foopy1:8080;foopy2:9090"); | |
| 569 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 570 | |
| 571 EXPECT_EQ(OK, callback4.WaitForResult()); | |
| 572 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); | |
| 573 } | |
| 574 | |
| 575 TEST(ProxyServiceTest, ProxyFallback_BadConfig) { | |
| 576 // Test proxy failover when the configuration is bad. | |
| 577 | |
| 578 MockProxyConfigService* config_service = | |
| 579 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 580 | |
| 581 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; | |
| 582 | |
| 583 ProxyService service(config_service, resolver); | |
| 584 | |
| 585 GURL url("http://www.google.com/"); | |
| 586 | |
| 587 // Get the proxy information. | |
| 588 ProxyInfo info; | |
| 589 TestCompletionCallback callback1; | |
| 590 int rv = service.ResolveProxy(url, &info, &callback1, NULL); | |
| 591 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 592 | |
| 593 EXPECT_EQ(GURL("http://foopy/proxy.pac"), | |
| 594 resolver->pending_set_pac_script_request()->pac_url()); | |
| 595 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 596 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 597 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 598 | |
| 599 resolver->pending_requests()[0]->results()->UseNamedProxy( | |
| 600 "foopy1:8080;foopy2:9090"); | |
| 601 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 602 | |
| 603 // The first item is valid. | |
| 604 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 605 EXPECT_FALSE(info.is_direct()); | |
| 606 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); | |
| 607 | |
| 608 // Fake a proxy error. | |
| 609 TestCompletionCallback callback2; | |
| 610 rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); | |
| 611 EXPECT_EQ(OK, rv); | |
| 612 | |
| 613 // The first proxy is ignored, and the second one is selected. | |
| 614 EXPECT_FALSE(info.is_direct()); | |
| 615 EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); | |
| 616 | |
| 617 // Fake a PAC failure. | |
| 618 ProxyInfo info2; | |
| 619 TestCompletionCallback callback3; | |
| 620 rv = service.ResolveProxy(url, &info2, &callback3, NULL); | |
| 621 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 622 | |
| 623 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 624 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 625 | |
| 626 resolver->pending_requests()[0]->CompleteNow(ERR_FAILED); | |
| 627 | |
| 628 // No proxy servers are returned. It's a direct connection. | |
| 629 EXPECT_EQ(ERR_FAILED, callback3.WaitForResult()); | |
| 630 EXPECT_TRUE(info2.is_direct()); | |
| 631 | |
| 632 // The PAC will now be fixed and will return a proxy server. | |
| 633 // It should also clear the list of bad proxies. | |
| 634 | |
| 635 // Try to resolve, it will still return "direct" because we have no reason | |
| 636 // to check the config since everything works. | |
| 637 ProxyInfo info3; | |
| 638 TestCompletionCallback callback4; | |
| 639 rv = service.ResolveProxy(url, &info3, &callback4, NULL); | |
| 640 EXPECT_EQ(OK, rv); | |
| 641 EXPECT_TRUE(info3.is_direct()); | |
| 642 | |
| 643 // But if the direct connection fails, we check if the ProxyInfo tried to | |
| 644 // resolve the proxy before, and if not (like in this case), we give the | |
| 645 // PAC another try. | |
| 646 TestCompletionCallback callback5; | |
| 647 rv = service.ReconsiderProxyAfterError(url, &info3, &callback5, NULL); | |
| 648 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 649 | |
| 650 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 651 EXPECT_EQ(url, resolver->pending_requests()[0]->url()); | |
| 652 | |
| 653 resolver->pending_requests()[0]->results()->UseNamedProxy( | |
| 654 "foopy1:8080;foopy2:9090"); | |
| 655 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 656 | |
| 657 // The first proxy is still there since the list of bad proxies got cleared. | |
| 658 EXPECT_EQ(OK, callback5.WaitForResult()); | |
| 659 EXPECT_FALSE(info3.is_direct()); | |
| 660 EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI()); | |
| 661 } | |
| 662 | |
| 663 TEST(ProxyServiceTest, ProxyBypassList) { | |
| 664 // Test what happens when a proxy bypass list is specified. | |
| 665 | |
| 666 ProxyInfo info; | |
| 667 ProxyConfig config; | |
| 668 config.proxy_rules.ParseFromString("foopy1:8080;foopy2:9090"); | |
| 669 config.auto_detect = false; | |
| 670 config.proxy_bypass_local_names = true; | |
| 671 | |
| 672 { | |
| 673 ProxyService service(new MockProxyConfigService(config), | |
| 674 new MockAsyncProxyResolver()); | |
| 675 GURL url("http://www.google.com/"); | |
| 676 // Get the proxy information. | |
| 677 TestCompletionCallback callback; | |
| 678 int rv = service.ResolveProxy(url, &info, &callback, NULL); | |
| 679 EXPECT_EQ(OK, rv); | |
| 680 EXPECT_FALSE(info.is_direct()); | |
| 681 } | |
| 682 | |
| 683 { | |
| 684 ProxyService service(new MockProxyConfigService(config), | |
| 685 new MockAsyncProxyResolver()); | |
| 686 GURL test_url("http://local"); | |
| 687 TestCompletionCallback callback; | |
| 688 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 689 EXPECT_EQ(OK, rv); | |
| 690 EXPECT_TRUE(info.is_direct()); | |
| 691 } | |
| 692 | |
| 693 config.proxy_bypass.clear(); | |
| 694 config.proxy_bypass.push_back("*.org"); | |
| 695 config.proxy_bypass_local_names = true; | |
| 696 { | |
| 697 ProxyService service(new MockProxyConfigService(config), | |
| 698 new MockAsyncProxyResolver); | |
| 699 GURL test_url("http://www.webkit.org"); | |
| 700 TestCompletionCallback callback; | |
| 701 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 702 EXPECT_EQ(OK, rv); | |
| 703 EXPECT_TRUE(info.is_direct()); | |
| 704 } | |
| 705 | |
| 706 config.proxy_bypass.clear(); | |
| 707 config.proxy_bypass.push_back("*.org"); | |
| 708 config.proxy_bypass.push_back("7*"); | |
| 709 config.proxy_bypass_local_names = true; | |
| 710 { | |
| 711 ProxyService service(new MockProxyConfigService(config), | |
| 712 new MockAsyncProxyResolver); | |
| 713 GURL test_url("http://74.125.19.147"); | |
| 714 TestCompletionCallback callback; | |
| 715 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 716 EXPECT_EQ(OK, rv); | |
| 717 EXPECT_TRUE(info.is_direct()); | |
| 718 } | |
| 719 | |
| 720 config.proxy_bypass.clear(); | |
| 721 config.proxy_bypass.push_back("*.org"); | |
| 722 config.proxy_bypass_local_names = true; | |
| 723 { | |
| 724 ProxyService service(new MockProxyConfigService(config), | |
| 725 new MockAsyncProxyResolver); | |
| 726 GURL test_url("http://www.msn.com"); | |
| 727 TestCompletionCallback callback; | |
| 728 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 729 EXPECT_EQ(OK, rv); | |
| 730 EXPECT_FALSE(info.is_direct()); | |
| 731 } | |
| 732 | |
| 733 config.proxy_bypass.clear(); | |
| 734 config.proxy_bypass.push_back("*.MSN.COM"); | |
| 735 config.proxy_bypass_local_names = true; | |
| 736 { | |
| 737 ProxyService service(new MockProxyConfigService(config), | |
| 738 new MockAsyncProxyResolver); | |
| 739 GURL test_url("http://www.msnbc.msn.com"); | |
| 740 TestCompletionCallback callback; | |
| 741 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 742 EXPECT_EQ(OK, rv); | |
| 743 EXPECT_TRUE(info.is_direct()); | |
| 744 } | |
| 745 | |
| 746 config.proxy_bypass.clear(); | |
| 747 config.proxy_bypass.push_back("*.msn.com"); | |
| 748 config.proxy_bypass_local_names = true; | |
| 749 { | |
| 750 ProxyService service(new MockProxyConfigService(config), | |
| 751 new MockAsyncProxyResolver); | |
| 752 GURL test_url("HTTP://WWW.MSNBC.MSN.COM"); | |
| 753 TestCompletionCallback callback; | |
| 754 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 755 EXPECT_EQ(OK, rv); | |
| 756 EXPECT_TRUE(info.is_direct()); | |
| 757 } | |
| 758 } | |
| 759 | |
| 760 TEST(ProxyServiceTest, ProxyBypassListWithPorts) { | |
| 761 // Test port specification in bypass list entries. | |
| 762 ProxyInfo info; | |
| 763 ProxyConfig config; | |
| 764 config.proxy_rules.ParseFromString("foopy1:8080;foopy2:9090"); | |
| 765 config.auto_detect = false; | |
| 766 config.proxy_bypass_local_names = false; | |
| 767 | |
| 768 config.proxy_bypass.clear(); | |
| 769 config.proxy_bypass.push_back("*.example.com:99"); | |
| 770 { | |
| 771 ProxyService service(new MockProxyConfigService(config), | |
| 772 new MockAsyncProxyResolver); | |
| 773 { | |
| 774 GURL test_url("http://www.example.com:99"); | |
| 775 TestCompletionCallback callback; | |
| 776 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 777 EXPECT_EQ(OK, rv); | |
| 778 EXPECT_TRUE(info.is_direct()); | |
| 779 } | |
| 780 { | |
| 781 GURL test_url("http://www.example.com:100"); | |
| 782 TestCompletionCallback callback; | |
| 783 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 784 EXPECT_EQ(OK, rv); | |
| 785 EXPECT_FALSE(info.is_direct()); | |
| 786 } | |
| 787 { | |
| 788 GURL test_url("http://www.example.com"); | |
| 789 TestCompletionCallback callback; | |
| 790 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 791 EXPECT_EQ(OK, rv); | |
| 792 EXPECT_FALSE(info.is_direct()); | |
| 793 } | |
| 794 } | |
| 795 | |
| 796 config.proxy_bypass.clear(); | |
| 797 config.proxy_bypass.push_back("*.example.com:80"); | |
| 798 { | |
| 799 ProxyService service(new MockProxyConfigService(config), | |
| 800 new MockAsyncProxyResolver); | |
| 801 GURL test_url("http://www.example.com"); | |
| 802 TestCompletionCallback callback; | |
| 803 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 804 EXPECT_EQ(OK, rv); | |
| 805 EXPECT_TRUE(info.is_direct()); | |
| 806 } | |
| 807 | |
| 808 config.proxy_bypass.clear(); | |
| 809 config.proxy_bypass.push_back("*.example.com"); | |
| 810 { | |
| 811 ProxyService service(new MockProxyConfigService(config), | |
| 812 new MockAsyncProxyResolver); | |
| 813 GURL test_url("http://www.example.com:99"); | |
| 814 TestCompletionCallback callback; | |
| 815 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 816 EXPECT_EQ(OK, rv); | |
| 817 EXPECT_TRUE(info.is_direct()); | |
| 818 } | |
| 819 | |
| 820 // IPv6 with port. | |
| 821 config.proxy_bypass.clear(); | |
| 822 config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]:99"); | |
| 823 { | |
| 824 ProxyService service(new MockProxyConfigService(config), | |
| 825 new MockAsyncProxyResolver); | |
| 826 { | |
| 827 GURL test_url("http://[3ffe:2a00:100:7031::1]:99/"); | |
| 828 TestCompletionCallback callback; | |
| 829 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 830 EXPECT_EQ(OK, rv); | |
| 831 EXPECT_TRUE(info.is_direct()); | |
| 832 } | |
| 833 { | |
| 834 GURL test_url("http://[3ffe:2a00:100:7031::1]/"); | |
| 835 TestCompletionCallback callback; | |
| 836 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 837 EXPECT_EQ(OK, rv); | |
| 838 EXPECT_FALSE(info.is_direct()); | |
| 839 } | |
| 840 } | |
| 841 | |
| 842 // IPv6 without port. The bypass entry ought to work without the | |
| 843 // brackets, but the bypass matching logic in ProxyService is | |
| 844 // currently limited. | |
| 845 config.proxy_bypass.clear(); | |
| 846 config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]"); | |
| 847 { | |
| 848 ProxyService service(new MockProxyConfigService(config), | |
| 849 new MockAsyncProxyResolver); | |
| 850 { | |
| 851 GURL test_url("http://[3ffe:2a00:100:7031::1]:99/"); | |
| 852 TestCompletionCallback callback; | |
| 853 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 854 EXPECT_EQ(OK, rv); | |
| 855 EXPECT_TRUE(info.is_direct()); | |
| 856 } | |
| 857 { | |
| 858 GURL test_url("http://[3ffe:2a00:100:7031::1]/"); | |
| 859 TestCompletionCallback callback; | |
| 860 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 861 EXPECT_EQ(OK, rv); | |
| 862 EXPECT_TRUE(info.is_direct()); | |
| 863 } | |
| 864 } | |
| 865 } | |
| 866 | |
| 867 TEST(ProxyServiceTest, PerProtocolProxyTests) { | |
| 868 ProxyConfig config; | |
| 869 config.proxy_rules.ParseFromString("http=foopy1:8080;https=foopy2:8080"); | |
| 870 config.auto_detect = false; | |
| 871 { | |
| 872 ProxyService service(new MockProxyConfigService(config), | |
| 873 new MockAsyncProxyResolver); | |
| 874 GURL test_url("http://www.msn.com"); | |
| 875 ProxyInfo info; | |
| 876 TestCompletionCallback callback; | |
| 877 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 878 EXPECT_EQ(OK, rv); | |
| 879 EXPECT_FALSE(info.is_direct()); | |
| 880 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); | |
| 881 } | |
| 882 { | |
| 883 ProxyService service(new MockProxyConfigService(config), | |
| 884 new MockAsyncProxyResolver); | |
| 885 GURL test_url("ftp://ftp.google.com"); | |
| 886 ProxyInfo info; | |
| 887 TestCompletionCallback callback; | |
| 888 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 889 EXPECT_EQ(OK, rv); | |
| 890 EXPECT_TRUE(info.is_direct()); | |
| 891 EXPECT_EQ("direct://", info.proxy_server().ToURI()); | |
| 892 } | |
| 893 { | |
| 894 ProxyService service(new MockProxyConfigService(config), | |
| 895 new MockAsyncProxyResolver); | |
| 896 GURL test_url("https://webbranch.techcu.com"); | |
| 897 ProxyInfo info; | |
| 898 TestCompletionCallback callback; | |
| 899 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 900 EXPECT_EQ(OK, rv); | |
| 901 EXPECT_FALSE(info.is_direct()); | |
| 902 EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI()); | |
| 903 } | |
| 904 { | |
| 905 config.proxy_rules.ParseFromString("foopy1:8080"); | |
| 906 ProxyService service(new MockProxyConfigService(config), | |
| 907 new MockAsyncProxyResolver); | |
| 908 GURL test_url("http://www.microsoft.com"); | |
| 909 ProxyInfo info; | |
| 910 TestCompletionCallback callback; | |
| 911 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 912 EXPECT_EQ(OK, rv); | |
| 913 EXPECT_FALSE(info.is_direct()); | |
| 914 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); | |
| 915 } | |
| 916 } | |
| 917 | |
| 918 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries | |
| 919 // fall back to the SOCKS proxy. | |
| 920 TEST(ProxyServiceTest, DefaultProxyFallbackToSOCKS) { | |
| 921 ProxyConfig config; | |
| 922 config.proxy_rules.ParseFromString("http=foopy1:8080;socks=foopy2:1080"); | |
| 923 config.auto_detect = false; | |
| 924 EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
| 925 config.proxy_rules.type); | |
| 926 | |
| 927 { | |
| 928 ProxyService service(new MockProxyConfigService(config), | |
| 929 new MockAsyncProxyResolver); | |
| 930 GURL test_url("http://www.msn.com"); | |
| 931 ProxyInfo info; | |
| 932 TestCompletionCallback callback; | |
| 933 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 934 EXPECT_EQ(OK, rv); | |
| 935 EXPECT_FALSE(info.is_direct()); | |
| 936 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); | |
| 937 } | |
| 938 { | |
| 939 ProxyService service(new MockProxyConfigService(config), | |
| 940 new MockAsyncProxyResolver); | |
| 941 GURL test_url("ftp://ftp.google.com"); | |
| 942 ProxyInfo info; | |
| 943 TestCompletionCallback callback; | |
| 944 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 945 EXPECT_EQ(OK, rv); | |
| 946 EXPECT_FALSE(info.is_direct()); | |
| 947 EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI()); | |
| 948 } | |
| 949 { | |
| 950 ProxyService service(new MockProxyConfigService(config), | |
| 951 new MockAsyncProxyResolver); | |
| 952 GURL test_url("https://webbranch.techcu.com"); | |
| 953 ProxyInfo info; | |
| 954 TestCompletionCallback callback; | |
| 955 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 956 EXPECT_EQ(OK, rv); | |
| 957 EXPECT_FALSE(info.is_direct()); | |
| 958 EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI()); | |
| 959 } | |
| 960 { | |
| 961 ProxyService service(new MockProxyConfigService(config), | |
| 962 new MockAsyncProxyResolver); | |
| 963 GURL test_url("unknown://www.microsoft.com"); | |
| 964 ProxyInfo info; | |
| 965 TestCompletionCallback callback; | |
| 966 int rv = service.ResolveProxy(test_url, &info, &callback, NULL); | |
| 967 EXPECT_EQ(OK, rv); | |
| 968 EXPECT_FALSE(info.is_direct()); | |
| 969 EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI()); | |
| 970 } | |
| 971 } | |
| 972 | |
| 973 // Test cancellation of an in-progress request. | |
| 974 TEST(ProxyServiceTest, CancelInProgressRequest) { | |
| 975 MockProxyConfigService* config_service = | |
| 976 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 977 | |
| 978 MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; | |
| 979 | |
| 980 ProxyService service(config_service, resolver); | |
| 981 | |
| 982 // Start 3 requests. | |
| 983 | |
| 984 ProxyInfo info1; | |
| 985 TestCompletionCallback callback1; | |
| 986 int rv = service.ResolveProxy( | |
| 987 GURL("http://request1"), &info1, &callback1, NULL); | |
| 988 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 989 | |
| 990 // Nothing has been sent to the proxy resolver yet, since the proxy | |
| 991 // resolver has not been configured yet. | |
| 992 ASSERT_EQ(0u, resolver->pending_requests().size()); | |
| 993 | |
| 994 // Successfully initialize the PAC script. | |
| 995 EXPECT_EQ(GURL("http://foopy/proxy.pac"), | |
| 996 resolver->pending_set_pac_script_request()->pac_url()); | |
| 997 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 998 | |
| 999 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 1000 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); | |
| 1001 | |
| 1002 ProxyInfo info2; | |
| 1003 TestCompletionCallback callback2; | |
| 1004 ProxyService::PacRequest* request2; | |
| 1005 rv = service.ResolveProxy( | |
| 1006 GURL("http://request2"), &info2, &callback2, &request2); | |
| 1007 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1008 ASSERT_EQ(2u, resolver->pending_requests().size()); | |
| 1009 EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); | |
| 1010 | |
| 1011 ProxyInfo info3; | |
| 1012 TestCompletionCallback callback3; | |
| 1013 rv = service.ResolveProxy( | |
| 1014 GURL("http://request3"), &info3, &callback3, NULL); | |
| 1015 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1016 ASSERT_EQ(3u, resolver->pending_requests().size()); | |
| 1017 EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url()); | |
| 1018 | |
| 1019 // Cancel the second request | |
| 1020 service.CancelPacRequest(request2); | |
| 1021 | |
| 1022 ASSERT_EQ(2u, resolver->pending_requests().size()); | |
| 1023 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); | |
| 1024 EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url()); | |
| 1025 | |
| 1026 // Complete the two un-cancelled requests. | |
| 1027 // We complete the last one first, just to mix it up a bit. | |
| 1028 resolver->pending_requests()[1]->results()->UseNamedProxy("request3:80"); | |
| 1029 resolver->pending_requests()[1]->CompleteNow(OK); | |
| 1030 | |
| 1031 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); | |
| 1032 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 1033 | |
| 1034 // Complete and verify that requests ran as expected. | |
| 1035 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 1036 EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); | |
| 1037 | |
| 1038 EXPECT_FALSE(callback2.have_result()); // Cancelled. | |
| 1039 ASSERT_EQ(1u, resolver->cancelled_requests().size()); | |
| 1040 EXPECT_EQ(GURL("http://request2"), resolver->cancelled_requests()[0]->url()); | |
| 1041 | |
| 1042 EXPECT_EQ(OK, callback3.WaitForResult()); | |
| 1043 EXPECT_EQ("request3:80", info3.proxy_server().ToURI()); | |
| 1044 } | |
| 1045 | |
| 1046 // Test the initial PAC download for ProxyResolverWithoutFetch. | |
| 1047 TEST(ProxyServiceTest, InitialPACScriptDownload) { | |
| 1048 MockProxyConfigService* config_service = | |
| 1049 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 1050 | |
| 1051 MockAsyncProxyResolverExpectsBytes* resolver = | |
| 1052 new MockAsyncProxyResolverExpectsBytes; | |
| 1053 | |
| 1054 ProxyService service(config_service, resolver); | |
| 1055 | |
| 1056 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; | |
| 1057 service.SetProxyScriptFetcher(fetcher); | |
| 1058 | |
| 1059 // Start 3 requests. | |
| 1060 | |
| 1061 ProxyInfo info1; | |
| 1062 TestCompletionCallback callback1; | |
| 1063 int rv = service.ResolveProxy( | |
| 1064 GURL("http://request1"), &info1, &callback1, NULL); | |
| 1065 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1066 | |
| 1067 // The first request should have triggered download of PAC script. | |
| 1068 EXPECT_TRUE(fetcher->has_pending_request()); | |
| 1069 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); | |
| 1070 | |
| 1071 ProxyInfo info2; | |
| 1072 TestCompletionCallback callback2; | |
| 1073 rv = service.ResolveProxy( | |
| 1074 GURL("http://request2"), &info2, &callback2, NULL); | |
| 1075 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1076 | |
| 1077 ProxyInfo info3; | |
| 1078 TestCompletionCallback callback3; | |
| 1079 rv = service.ResolveProxy( | |
| 1080 GURL("http://request3"), &info3, &callback3, NULL); | |
| 1081 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1082 | |
| 1083 // Nothing has been sent to the resolver yet. | |
| 1084 EXPECT_TRUE(resolver->pending_requests().empty()); | |
| 1085 | |
| 1086 // At this point the ProxyService should be waiting for the | |
| 1087 // ProxyScriptFetcher to invoke its completion callback, notifying it of | |
| 1088 // PAC script download completion. | |
| 1089 fetcher->NotifyFetchCompletion(OK, "pac-v1"); | |
| 1090 | |
| 1091 // Now that the PAC script is downloaded, it will have been sent to the proxy | |
| 1092 // resolver. | |
| 1093 EXPECT_EQ("pac-v1", resolver->pending_set_pac_script_request()->pac_bytes()); | |
| 1094 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 1095 | |
| 1096 ASSERT_EQ(3u, resolver->pending_requests().size()); | |
| 1097 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); | |
| 1098 EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); | |
| 1099 EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url()); | |
| 1100 | |
| 1101 // Complete all the requests (in some order). | |
| 1102 // Note that as we complete requests, they shift up in |pending_requests()|. | |
| 1103 | |
| 1104 resolver->pending_requests()[2]->results()->UseNamedProxy("request3:80"); | |
| 1105 resolver->pending_requests()[2]->CompleteNow(OK); | |
| 1106 | |
| 1107 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); | |
| 1108 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 1109 | |
| 1110 resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80"); | |
| 1111 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 1112 | |
| 1113 // Complete and verify that requests ran as expected. | |
| 1114 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 1115 EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); | |
| 1116 | |
| 1117 EXPECT_EQ(OK, callback2.WaitForResult()); | |
| 1118 EXPECT_EQ("request2:80", info2.proxy_server().ToURI()); | |
| 1119 | |
| 1120 EXPECT_EQ(OK, callback3.WaitForResult()); | |
| 1121 EXPECT_EQ("request3:80", info3.proxy_server().ToURI()); | |
| 1122 } | |
| 1123 | |
| 1124 // Test cancellation of a request, while the PAC script is being fetched. | |
| 1125 TEST(ProxyServiceTest, CancelWhilePACFetching) { | |
| 1126 MockProxyConfigService* config_service = | |
| 1127 new MockProxyConfigService("http://foopy/proxy.pac"); | |
| 1128 | |
| 1129 MockAsyncProxyResolverExpectsBytes* resolver = | |
| 1130 new MockAsyncProxyResolverExpectsBytes; | |
| 1131 | |
| 1132 ProxyService service(config_service, resolver); | |
| 1133 | |
| 1134 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; | |
| 1135 service.SetProxyScriptFetcher(fetcher); | |
| 1136 | |
| 1137 // Start 3 requests. | |
| 1138 ProxyInfo info1; | |
| 1139 TestCompletionCallback callback1; | |
| 1140 ProxyService::PacRequest* request1; | |
| 1141 int rv = service.ResolveProxy( | |
| 1142 GURL("http://request1"), &info1, &callback1, &request1); | |
| 1143 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1144 | |
| 1145 // The first request should have triggered download of PAC script. | |
| 1146 EXPECT_TRUE(fetcher->has_pending_request()); | |
| 1147 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); | |
| 1148 | |
| 1149 ProxyInfo info2; | |
| 1150 TestCompletionCallback callback2; | |
| 1151 ProxyService::PacRequest* request2; | |
| 1152 rv = service.ResolveProxy( | |
| 1153 GURL("http://request2"), &info2, &callback2, &request2); | |
| 1154 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1155 | |
| 1156 ProxyInfo info3; | |
| 1157 TestCompletionCallback callback3; | |
| 1158 rv = service.ResolveProxy( | |
| 1159 GURL("http://request3"), &info3, &callback3, NULL); | |
| 1160 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1161 | |
| 1162 // Nothing has been sent to the resolver yet. | |
| 1163 EXPECT_TRUE(resolver->pending_requests().empty()); | |
| 1164 | |
| 1165 // Cancel the first 2 requests. | |
| 1166 service.CancelPacRequest(request1); | |
| 1167 service.CancelPacRequest(request2); | |
| 1168 | |
| 1169 // At this point the ProxyService should be waiting for the | |
| 1170 // ProxyScriptFetcher to invoke its completion callback, notifying it of | |
| 1171 // PAC script download completion. | |
| 1172 fetcher->NotifyFetchCompletion(OK, "pac-v1"); | |
| 1173 | |
| 1174 // Now that the PAC script is downloaded, it will have been sent to the | |
| 1175 // proxy resolver. | |
| 1176 EXPECT_EQ("pac-v1", resolver->pending_set_pac_script_request()->pac_bytes()); | |
| 1177 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 1178 | |
| 1179 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 1180 EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[0]->url()); | |
| 1181 | |
| 1182 // Complete all the requests. | |
| 1183 resolver->pending_requests()[0]->results()->UseNamedProxy("request3:80"); | |
| 1184 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 1185 | |
| 1186 EXPECT_EQ(OK, callback3.WaitForResult()); | |
| 1187 EXPECT_EQ("request3:80", info3.proxy_server().ToURI()); | |
| 1188 | |
| 1189 EXPECT_TRUE(resolver->cancelled_requests().empty()); | |
| 1190 | |
| 1191 EXPECT_FALSE(callback1.have_result()); // Cancelled. | |
| 1192 EXPECT_FALSE(callback2.have_result()); // Cancelled. | |
| 1193 } | |
| 1194 | |
| 1195 // Test that if auto-detect fails, we fall-back to the custom pac. | |
| 1196 TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac) { | |
| 1197 ProxyConfig config; | |
| 1198 config.auto_detect = true; | |
| 1199 config.pac_url = GURL("http://foopy/proxy.pac"); | |
| 1200 config.proxy_rules.ParseFromString("http=foopy:80"); // Won't be used. | |
| 1201 | |
| 1202 MockProxyConfigService* config_service = new MockProxyConfigService(config); | |
| 1203 MockAsyncProxyResolverExpectsBytes* resolver = | |
| 1204 new MockAsyncProxyResolverExpectsBytes; | |
| 1205 ProxyService service(config_service, resolver); | |
| 1206 | |
| 1207 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; | |
| 1208 service.SetProxyScriptFetcher(fetcher); | |
| 1209 | |
| 1210 // Start 2 requests. | |
| 1211 | |
| 1212 ProxyInfo info1; | |
| 1213 TestCompletionCallback callback1; | |
| 1214 int rv = service.ResolveProxy( | |
| 1215 GURL("http://request1"), &info1, &callback1, NULL); | |
| 1216 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1217 | |
| 1218 ProxyInfo info2; | |
| 1219 TestCompletionCallback callback2; | |
| 1220 ProxyService::PacRequest* request2; | |
| 1221 rv = service.ResolveProxy( | |
| 1222 GURL("http://request2"), &info2, &callback2, &request2); | |
| 1223 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1224 | |
| 1225 // Check that nothing has been sent to the proxy resolver yet. | |
| 1226 ASSERT_EQ(0u, resolver->pending_requests().size()); | |
| 1227 | |
| 1228 // It should be trying to auto-detect first -- FAIL the autodetect during | |
| 1229 // the script download. | |
| 1230 EXPECT_TRUE(fetcher->has_pending_request()); | |
| 1231 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url()); | |
| 1232 fetcher->NotifyFetchCompletion(ERR_FAILED, ""); | |
| 1233 | |
| 1234 // Next it should be trying the custom PAC url. | |
| 1235 EXPECT_TRUE(fetcher->has_pending_request()); | |
| 1236 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); | |
| 1237 fetcher->NotifyFetchCompletion(OK, "custom-pac-script"); | |
| 1238 | |
| 1239 EXPECT_EQ("custom-pac-script", | |
| 1240 resolver->pending_set_pac_script_request()->pac_bytes()); | |
| 1241 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 1242 | |
| 1243 // Now finally, the pending requests should have been sent to the resolver | |
| 1244 // (which was initialized with custom PAC script). | |
| 1245 | |
| 1246 ASSERT_EQ(2u, resolver->pending_requests().size()); | |
| 1247 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); | |
| 1248 EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); | |
| 1249 | |
| 1250 // Complete the pending requests. | |
| 1251 resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80"); | |
| 1252 resolver->pending_requests()[1]->CompleteNow(OK); | |
| 1253 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); | |
| 1254 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 1255 | |
| 1256 // Verify that requests ran as expected. | |
| 1257 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 1258 EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); | |
| 1259 | |
| 1260 EXPECT_EQ(OK, callback2.WaitForResult()); | |
| 1261 EXPECT_EQ("request2:80", info2.proxy_server().ToURI()); | |
| 1262 } | |
| 1263 | |
| 1264 // This is the same test as FallbackFromAutodetectToCustomPac, except | |
| 1265 // the auto-detect script fails parsing rather than downloading. | |
| 1266 TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) { | |
| 1267 ProxyConfig config; | |
| 1268 config.auto_detect = true; | |
| 1269 config.pac_url = GURL("http://foopy/proxy.pac"); | |
| 1270 config.proxy_rules.ParseFromString("http=foopy:80"); // Won't be used. | |
| 1271 | |
| 1272 MockProxyConfigService* config_service = new MockProxyConfigService(config); | |
| 1273 MockAsyncProxyResolverExpectsBytes* resolver = | |
| 1274 new MockAsyncProxyResolverExpectsBytes; | |
| 1275 ProxyService service(config_service, resolver); | |
| 1276 | |
| 1277 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; | |
| 1278 service.SetProxyScriptFetcher(fetcher); | |
| 1279 | |
| 1280 // Start 2 requests. | |
| 1281 | |
| 1282 ProxyInfo info1; | |
| 1283 TestCompletionCallback callback1; | |
| 1284 int rv = service.ResolveProxy( | |
| 1285 GURL("http://request1"), &info1, &callback1, NULL); | |
| 1286 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1287 | |
| 1288 ProxyInfo info2; | |
| 1289 TestCompletionCallback callback2; | |
| 1290 ProxyService::PacRequest* request2; | |
| 1291 rv = service.ResolveProxy( | |
| 1292 GURL("http://request2"), &info2, &callback2, &request2); | |
| 1293 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1294 | |
| 1295 // Check that nothing has been sent to the proxy resolver yet. | |
| 1296 ASSERT_EQ(0u, resolver->pending_requests().size()); | |
| 1297 | |
| 1298 // It should be trying to auto-detect first -- succeed the download. | |
| 1299 EXPECT_TRUE(fetcher->has_pending_request()); | |
| 1300 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url()); | |
| 1301 fetcher->NotifyFetchCompletion(OK, "invalid-script-contents"); | |
| 1302 | |
| 1303 // Simulate a parse error. | |
| 1304 EXPECT_EQ("invalid-script-contents", | |
| 1305 resolver->pending_set_pac_script_request()->pac_bytes()); | |
| 1306 resolver->pending_set_pac_script_request()->CompleteNow( | |
| 1307 ERR_PAC_SCRIPT_FAILED); | |
| 1308 | |
| 1309 // Next it should be trying the custom PAC url. | |
| 1310 EXPECT_TRUE(fetcher->has_pending_request()); | |
| 1311 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); | |
| 1312 fetcher->NotifyFetchCompletion(OK, "custom-pac-script"); | |
| 1313 | |
| 1314 EXPECT_EQ("custom-pac-script", | |
| 1315 resolver->pending_set_pac_script_request()->pac_bytes()); | |
| 1316 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 1317 | |
| 1318 // Now finally, the pending requests should have been sent to the resolver | |
| 1319 // (which was initialized with custom PAC script). | |
| 1320 | |
| 1321 ASSERT_EQ(2u, resolver->pending_requests().size()); | |
| 1322 EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); | |
| 1323 EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); | |
| 1324 | |
| 1325 // Complete the pending requests. | |
| 1326 resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80"); | |
| 1327 resolver->pending_requests()[1]->CompleteNow(OK); | |
| 1328 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); | |
| 1329 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 1330 | |
| 1331 // Verify that requests ran as expected. | |
| 1332 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 1333 EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); | |
| 1334 | |
| 1335 EXPECT_EQ(OK, callback2.WaitForResult()); | |
| 1336 EXPECT_EQ("request2:80", info2.proxy_server().ToURI()); | |
| 1337 } | |
| 1338 | |
| 1339 // Test that if all of auto-detect, a custom PAC script, and manual settings | |
| 1340 // are given, then we will try them in that order. | |
| 1341 TEST(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) { | |
| 1342 ProxyConfig config; | |
| 1343 config.auto_detect = true; | |
| 1344 config.pac_url = GURL("http://foopy/proxy.pac"); | |
| 1345 config.proxy_rules.ParseFromString("http=foopy:80"); | |
| 1346 | |
| 1347 MockProxyConfigService* config_service = new MockProxyConfigService(config); | |
| 1348 MockAsyncProxyResolverExpectsBytes* resolver = | |
| 1349 new MockAsyncProxyResolverExpectsBytes; | |
| 1350 ProxyService service(config_service, resolver); | |
| 1351 | |
| 1352 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; | |
| 1353 service.SetProxyScriptFetcher(fetcher); | |
| 1354 | |
| 1355 // Start 2 requests. | |
| 1356 | |
| 1357 ProxyInfo info1; | |
| 1358 TestCompletionCallback callback1; | |
| 1359 int rv = service.ResolveProxy( | |
| 1360 GURL("http://request1"), &info1, &callback1, NULL); | |
| 1361 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1362 | |
| 1363 ProxyInfo info2; | |
| 1364 TestCompletionCallback callback2; | |
| 1365 ProxyService::PacRequest* request2; | |
| 1366 rv = service.ResolveProxy( | |
| 1367 GURL("http://request2"), &info2, &callback2, &request2); | |
| 1368 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1369 | |
| 1370 // Check that nothing has been sent to the proxy resolver yet. | |
| 1371 ASSERT_EQ(0u, resolver->pending_requests().size()); | |
| 1372 | |
| 1373 // It should be trying to auto-detect first -- fail the download. | |
| 1374 EXPECT_TRUE(fetcher->has_pending_request()); | |
| 1375 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url()); | |
| 1376 fetcher->NotifyFetchCompletion(ERR_FAILED, ""); | |
| 1377 | |
| 1378 // Next it should be trying the custom PAC url -- fail the download. | |
| 1379 EXPECT_TRUE(fetcher->has_pending_request()); | |
| 1380 EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); | |
| 1381 fetcher->NotifyFetchCompletion(ERR_FAILED, ""); | |
| 1382 | |
| 1383 // Since we never managed to initialize a ProxyResolver, nothing should have | |
| 1384 // been sent to it. | |
| 1385 ASSERT_EQ(0u, resolver->pending_requests().size()); | |
| 1386 | |
| 1387 // Verify that requests ran as expected -- they should have fallen back to | |
| 1388 // the manual proxy configuration for HTTP urls. | |
| 1389 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 1390 EXPECT_EQ("foopy:80", info1.proxy_server().ToURI()); | |
| 1391 | |
| 1392 EXPECT_EQ(OK, callback2.WaitForResult()); | |
| 1393 EXPECT_EQ("foopy:80", info2.proxy_server().ToURI()); | |
| 1394 } | |
| 1395 | |
| 1396 // Test that the bypass rules are NOT applied when using autodetect. | |
| 1397 TEST(ProxyServiceTest, BypassDoesntApplyToPac) { | |
| 1398 ProxyConfig config; | |
| 1399 config.auto_detect = true; | |
| 1400 config.pac_url = GURL("http://foopy/proxy.pac"); | |
| 1401 config.proxy_rules.ParseFromString("http=foopy:80"); // Not used. | |
| 1402 config.proxy_bypass.push_back("www.google.com"); | |
| 1403 | |
| 1404 MockProxyConfigService* config_service = new MockProxyConfigService(config); | |
| 1405 MockAsyncProxyResolverExpectsBytes* resolver = | |
| 1406 new MockAsyncProxyResolverExpectsBytes; | |
| 1407 ProxyService service(config_service, resolver); | |
| 1408 | |
| 1409 MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; | |
| 1410 service.SetProxyScriptFetcher(fetcher); | |
| 1411 | |
| 1412 // Start 1 requests. | |
| 1413 | |
| 1414 ProxyInfo info1; | |
| 1415 TestCompletionCallback callback1; | |
| 1416 int rv = service.ResolveProxy( | |
| 1417 GURL("http://www.google.com"), &info1, &callback1, NULL); | |
| 1418 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1419 | |
| 1420 // Check that nothing has been sent to the proxy resolver yet. | |
| 1421 ASSERT_EQ(0u, resolver->pending_requests().size()); | |
| 1422 | |
| 1423 // It should be trying to auto-detect first -- succeed the download. | |
| 1424 EXPECT_TRUE(fetcher->has_pending_request()); | |
| 1425 EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url()); | |
| 1426 fetcher->NotifyFetchCompletion(OK, "auto-detect"); | |
| 1427 | |
| 1428 EXPECT_EQ("auto-detect", | |
| 1429 resolver->pending_set_pac_script_request()->pac_bytes()); | |
| 1430 resolver->pending_set_pac_script_request()->CompleteNow(OK); | |
| 1431 | |
| 1432 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 1433 EXPECT_EQ(GURL("http://www.google.com"), | |
| 1434 resolver->pending_requests()[0]->url()); | |
| 1435 | |
| 1436 // Complete the pending request. | |
| 1437 resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); | |
| 1438 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 1439 | |
| 1440 // Verify that request ran as expected. | |
| 1441 EXPECT_EQ(OK, callback1.WaitForResult()); | |
| 1442 EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); | |
| 1443 | |
| 1444 // Start another request, it should pickup the bypass item. | |
| 1445 ProxyInfo info2; | |
| 1446 TestCompletionCallback callback2; | |
| 1447 rv = service.ResolveProxy( | |
| 1448 GURL("http://www.google.com"), &info2, &callback2, NULL); | |
| 1449 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1450 | |
| 1451 ASSERT_EQ(1u, resolver->pending_requests().size()); | |
| 1452 EXPECT_EQ(GURL("http://www.google.com"), | |
| 1453 resolver->pending_requests()[0]->url()); | |
| 1454 | |
| 1455 // Complete the pending request. | |
| 1456 resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80"); | |
| 1457 resolver->pending_requests()[0]->CompleteNow(OK); | |
| 1458 | |
| 1459 EXPECT_EQ(OK, callback2.WaitForResult()); | |
| 1460 EXPECT_EQ("request2:80", info2.proxy_server().ToURI()); | |
| 1461 } | |
| 1462 | |
| 1463 TEST(ProxyServiceTest, ResetProxyConfigService) { | |
| 1464 ProxyConfig config1; | |
| 1465 config1.proxy_rules.ParseFromString("foopy1:8080"); | |
| 1466 config1.auto_detect = false; | |
| 1467 ProxyService service(new MockProxyConfigService(config1), | |
| 1468 new MockAsyncProxyResolverExpectsBytes); | |
| 1469 | |
| 1470 ProxyInfo info; | |
| 1471 TestCompletionCallback callback1; | |
| 1472 int rv = service.ResolveProxy( | |
| 1473 GURL("http://request1"), &info, &callback1, NULL); | |
| 1474 EXPECT_EQ(OK, rv); | |
| 1475 EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); | |
| 1476 | |
| 1477 ProxyConfig config2; | |
| 1478 config2.proxy_rules.ParseFromString("foopy2:8080"); | |
| 1479 config2.auto_detect = false; | |
| 1480 service.ResetConfigService(new MockProxyConfigService(config2)); | |
| 1481 TestCompletionCallback callback2; | |
| 1482 rv = service.ResolveProxy(GURL("http://request2"), &info, &callback2, NULL); | |
| 1483 EXPECT_EQ(OK, rv); | |
| 1484 EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI()); | |
| 1485 } | |
| 1486 | |
| 1487 TEST(ProxyServiceTest, IsLocalName) { | |
| 1488 const struct { | |
| 1489 const char* url; | |
| 1490 bool expected_is_local; | |
| 1491 } tests[] = { | |
| 1492 // Single-component hostnames are considered local. | |
| 1493 {"http://localhost/x", true}, | |
| 1494 {"http://www", true}, | |
| 1495 | |
| 1496 // IPv4 loopback interface. | |
| 1497 {"http://127.0.0.1/x", true}, | |
| 1498 {"http://127.0.0.1:80/x", true}, | |
| 1499 | |
| 1500 // IPv6 loopback interface. | |
| 1501 {"http://[::1]:80/x", true}, | |
| 1502 {"http://[0:0::1]:6233/x", true}, | |
| 1503 {"http://[0:0:0:0:0:0:0:1]/x", true}, | |
| 1504 | |
| 1505 // Non-local URLs. | |
| 1506 {"http://foo.com/", false}, | |
| 1507 {"http://localhost.i/", false}, | |
| 1508 {"http://www.google.com/", false}, | |
| 1509 {"http://192.168.0.1/", false}, | |
| 1510 | |
| 1511 // Try with different protocols. | |
| 1512 {"ftp://127.0.0.1/x", true}, | |
| 1513 {"ftp://foobar.com/x", false}, | |
| 1514 | |
| 1515 // This is a bit of a gray-area, but GURL does not strip trailing dots | |
| 1516 // in host-names, so the following are considered non-local. | |
| 1517 {"http://www./x", false}, | |
| 1518 {"http://localhost./x", false}, | |
| 1519 }; | |
| 1520 | |
| 1521 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 1522 SCOPED_TRACE(StringPrintf("Test[%d]: %s", i, tests[i].url)); | |
| 1523 bool is_local = ProxyService::IsLocalName(GURL(tests[i].url)); | |
| 1524 EXPECT_EQ(tests[i].expected_is_local, is_local); | |
| 1525 } | |
| 1526 } | |
| 1527 | |
| 1528 } // namespace net | |
| OLD | NEW |