OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/proxy_service.h" | 5 #include "net/proxy/proxy_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "googleurl/src/gurl.h" | 15 #include "googleurl/src/gurl.h" |
| 16 #include "net/base/completion_callback.h" |
16 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
17 #include "net/base/net_log.h" | 18 #include "net/base/net_log.h" |
18 #include "net/base/net_util.h" | 19 #include "net/base/net_util.h" |
19 #include "net/proxy/dhcp_proxy_script_fetcher.h" | 20 #include "net/proxy/dhcp_proxy_script_fetcher.h" |
20 #include "net/proxy/init_proxy_resolver.h" | 21 #include "net/proxy/init_proxy_resolver.h" |
21 #include "net/proxy/multi_threaded_proxy_resolver.h" | 22 #include "net/proxy/multi_threaded_proxy_resolver.h" |
22 #include "net/proxy/network_delegate_error_observer.h" | 23 #include "net/proxy/network_delegate_error_observer.h" |
23 #include "net/proxy/proxy_config_service_fixed.h" | 24 #include "net/proxy/proxy_config_service_fixed.h" |
24 #include "net/proxy/proxy_resolver.h" | 25 #include "net/proxy/proxy_resolver.h" |
25 #include "net/proxy/proxy_resolver_js_bindings.h" | 26 #include "net/proxy/proxy_resolver_js_bindings.h" |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 | 318 |
318 class ProxyService::PacRequest | 319 class ProxyService::PacRequest |
319 : public base::RefCounted<ProxyService::PacRequest> { | 320 : public base::RefCounted<ProxyService::PacRequest> { |
320 public: | 321 public: |
321 PacRequest(ProxyService* service, | 322 PacRequest(ProxyService* service, |
322 const GURL& url, | 323 const GURL& url, |
323 ProxyInfo* results, | 324 ProxyInfo* results, |
324 OldCompletionCallback* user_callback, | 325 OldCompletionCallback* user_callback, |
325 const BoundNetLog& net_log) | 326 const BoundNetLog& net_log) |
326 : service_(service), | 327 : service_(service), |
327 user_callback_(user_callback), | 328 old_user_callback_(user_callback), |
328 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( | 329 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( |
329 this, &PacRequest::QueryComplete)), | 330 this, &PacRequest::QueryComplete)), |
330 results_(results), | 331 results_(results), |
331 url_(url), | 332 url_(url), |
332 resolve_job_(NULL), | 333 resolve_job_(NULL), |
333 config_id_(ProxyConfig::kInvalidConfigID), | 334 config_id_(ProxyConfig::kInvalidConfigID), |
334 net_log_(net_log) { | 335 net_log_(net_log) { |
335 DCHECK(user_callback); | 336 DCHECK(user_callback); |
336 } | 337 } |
337 | 338 |
| 339 PacRequest(ProxyService* service, |
| 340 const GURL& url, |
| 341 ProxyInfo* results, |
| 342 const net::CompletionCallback& user_callback, |
| 343 const BoundNetLog& net_log) |
| 344 : service_(service), |
| 345 old_user_callback_(NULL), |
| 346 user_callback_(user_callback), |
| 347 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( |
| 348 this, &PacRequest::QueryComplete)), |
| 349 results_(results), |
| 350 url_(url), |
| 351 resolve_job_(NULL), |
| 352 config_id_(ProxyConfig::kInvalidConfigID), |
| 353 net_log_(net_log) { |
| 354 DCHECK(!user_callback.is_null()); |
| 355 } |
| 356 |
338 // Starts the resolve proxy request. | 357 // Starts the resolve proxy request. |
339 int Start() { | 358 int Start() { |
340 DCHECK(!was_cancelled()); | 359 DCHECK(!was_cancelled()); |
341 DCHECK(!is_started()); | 360 DCHECK(!is_started()); |
342 | 361 |
343 DCHECK(service_->config_.is_valid()); | 362 DCHECK(service_->config_.is_valid()); |
344 | 363 |
345 config_id_ = service_->config_.id(); | 364 config_id_ = service_->config_.id(); |
346 | 365 |
347 return resolver()->GetProxyForURL( | 366 return resolver()->GetProxyForURL( |
(...skipping 22 matching lines...) Expand all Loading... |
370 } | 389 } |
371 | 390 |
372 void Cancel() { | 391 void Cancel() { |
373 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); | 392 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); |
374 | 393 |
375 if (is_started()) | 394 if (is_started()) |
376 CancelResolveJob(); | 395 CancelResolveJob(); |
377 | 396 |
378 // Mark as cancelled, to prevent accessing this again later. | 397 // Mark as cancelled, to prevent accessing this again later. |
379 service_ = NULL; | 398 service_ = NULL; |
380 user_callback_ = NULL; | 399 old_user_callback_ = NULL; |
| 400 user_callback_.Reset(); |
381 results_ = NULL; | 401 results_ = NULL; |
382 | 402 |
383 net_log_.EndEvent(NetLog::TYPE_PROXY_SERVICE, NULL); | 403 net_log_.EndEvent(NetLog::TYPE_PROXY_SERVICE, NULL); |
384 } | 404 } |
385 | 405 |
386 // Returns true if Cancel() has been called. | 406 // Returns true if Cancel() has been called. |
387 bool was_cancelled() const { return user_callback_ == NULL; } | 407 bool was_cancelled() const { |
| 408 return old_user_callback_ == NULL && user_callback_.is_null(); |
| 409 } |
388 | 410 |
389 // Helper to call after ProxyResolver completion (both synchronous and | 411 // Helper to call after ProxyResolver completion (both synchronous and |
390 // asynchronous). Fixes up the result that is to be returned to user. | 412 // asynchronous). Fixes up the result that is to be returned to user. |
391 int QueryDidComplete(int result_code) { | 413 int QueryDidComplete(int result_code) { |
392 DCHECK(!was_cancelled()); | 414 DCHECK(!was_cancelled()); |
393 | 415 |
394 // Make a note in the results which configuration was in use at the | 416 // Make a note in the results which configuration was in use at the |
395 // time of the resolve. | 417 // time of the resolve. |
396 results_->config_id_ = config_id_; | 418 results_->config_id_ = config_id_; |
397 | 419 |
(...skipping 16 matching lines...) Expand all Loading... |
414 friend class base::RefCounted<ProxyService::PacRequest>; | 436 friend class base::RefCounted<ProxyService::PacRequest>; |
415 | 437 |
416 ~PacRequest() {} | 438 ~PacRequest() {} |
417 | 439 |
418 // Callback for when the ProxyResolver request has completed. | 440 // Callback for when the ProxyResolver request has completed. |
419 void QueryComplete(int result_code) { | 441 void QueryComplete(int result_code) { |
420 result_code = QueryDidComplete(result_code); | 442 result_code = QueryDidComplete(result_code); |
421 | 443 |
422 // Remove this completed PacRequest from the service's pending list. | 444 // Remove this completed PacRequest from the service's pending list. |
423 /// (which will probably cause deletion of |this|). | 445 /// (which will probably cause deletion of |this|). |
424 OldCompletionCallback* callback = user_callback_; | 446 if (old_user_callback_) { |
425 service_->RemovePendingRequest(this); | 447 OldCompletionCallback* callback = old_user_callback_; |
426 | 448 service_->RemovePendingRequest(this); |
427 callback->Run(result_code); | 449 callback->Run(result_code); |
| 450 } else if (!user_callback_.is_null()){ |
| 451 net::CompletionCallback callback = user_callback_; |
| 452 service_->RemovePendingRequest(this); |
| 453 callback.Run(result_code); |
| 454 } |
428 } | 455 } |
429 | 456 |
430 ProxyResolver* resolver() const { return service_->resolver_.get(); } | 457 ProxyResolver* resolver() const { return service_->resolver_.get(); } |
431 | 458 |
432 // Note that we don't hold a reference to the ProxyService. Outstanding | 459 // Note that we don't hold a reference to the ProxyService. Outstanding |
433 // requests are cancelled during ~ProxyService, so this is guaranteed | 460 // requests are cancelled during ~ProxyService, so this is guaranteed |
434 // to be valid throughout our lifetime. | 461 // to be valid throughout our lifetime. |
435 ProxyService* service_; | 462 ProxyService* service_; |
436 OldCompletionCallback* user_callback_; | 463 OldCompletionCallback* old_user_callback_; |
| 464 net::CompletionCallback user_callback_; |
437 OldCompletionCallbackImpl<PacRequest> io_callback_; | 465 OldCompletionCallbackImpl<PacRequest> io_callback_; |
438 ProxyInfo* results_; | 466 ProxyInfo* results_; |
439 GURL url_; | 467 GURL url_; |
440 ProxyResolver::RequestHandle resolve_job_; | 468 ProxyResolver::RequestHandle resolve_job_; |
441 ProxyConfig::ID config_id_; // The config id when the resolve was started. | 469 ProxyConfig::ID config_id_; // The config id when the resolve was started. |
442 BoundNetLog net_log_; | 470 BoundNetLog net_log_; |
443 }; | 471 }; |
444 | 472 |
445 // ProxyService --------------------------------------------------------------- | 473 // ProxyService --------------------------------------------------------------- |
446 | 474 |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 DCHECK(!ContainsPendingRequest(req)); | 641 DCHECK(!ContainsPendingRequest(req)); |
614 pending_requests_.push_back(req); | 642 pending_requests_.push_back(req); |
615 | 643 |
616 // Completion will be notifed through |callback|, unless the caller cancels | 644 // Completion will be notifed through |callback|, unless the caller cancels |
617 // the request using |pac_request|. | 645 // the request using |pac_request|. |
618 if (pac_request) | 646 if (pac_request) |
619 *pac_request = req.get(); | 647 *pac_request = req.get(); |
620 return rv; // ERR_IO_PENDING | 648 return rv; // ERR_IO_PENDING |
621 } | 649 } |
622 | 650 |
| 651 int ProxyService::ResolveProxy(const GURL& raw_url, |
| 652 ProxyInfo* result, |
| 653 const net::CompletionCallback& callback, |
| 654 PacRequest** pac_request, |
| 655 const BoundNetLog& net_log) { |
| 656 DCHECK(CalledOnValidThread()); |
| 657 DCHECK(!callback.is_null()); |
| 658 |
| 659 net_log.BeginEvent(NetLog::TYPE_PROXY_SERVICE, NULL); |
| 660 |
| 661 config_service_->OnLazyPoll(); |
| 662 if (current_state_ == STATE_NONE) |
| 663 ApplyProxyConfigIfAvailable(); |
| 664 |
| 665 // Strip away any reference fragments and the username/password, as they |
| 666 // are not relevant to proxy resolution. |
| 667 GURL url = SimplifyUrlForRequest(raw_url); |
| 668 |
| 669 // Check if the request can be completed right away. (This is the case when |
| 670 // using a direct connection for example). |
| 671 int rv = TryToCompleteSynchronously(url, result); |
| 672 if (rv != ERR_IO_PENDING) |
| 673 return DidFinishResolvingProxy(result, rv, net_log); |
| 674 |
| 675 scoped_refptr<PacRequest> req( |
| 676 new PacRequest(this, url, result, callback, net_log)); |
| 677 |
| 678 if (current_state_ == STATE_READY) { |
| 679 // Start the resolve request. |
| 680 rv = req->Start(); |
| 681 if (rv != ERR_IO_PENDING) |
| 682 return req->QueryDidComplete(rv); |
| 683 } else { |
| 684 req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC, |
| 685 NULL); |
| 686 } |
| 687 |
| 688 DCHECK_EQ(ERR_IO_PENDING, rv); |
| 689 DCHECK(!ContainsPendingRequest(req)); |
| 690 pending_requests_.push_back(req); |
| 691 |
| 692 // Completion will be notified through |callback|, unless the caller cancels |
| 693 // the request using |pac_request|. |
| 694 if (pac_request) |
| 695 *pac_request = req.get(); |
| 696 return rv; // ERR_IO_PENDING |
| 697 } |
| 698 |
623 int ProxyService::TryToCompleteSynchronously(const GURL& url, | 699 int ProxyService::TryToCompleteSynchronously(const GURL& url, |
624 ProxyInfo* result) { | 700 ProxyInfo* result) { |
625 DCHECK_NE(STATE_NONE, current_state_); | 701 DCHECK_NE(STATE_NONE, current_state_); |
626 | 702 |
627 if (current_state_ != STATE_READY) | 703 if (current_state_ != STATE_READY) |
628 return ERR_IO_PENDING; // Still initializing. | 704 return ERR_IO_PENDING; // Still initializing. |
629 | 705 |
630 DCHECK_NE(config_.id(), ProxyConfig::kInvalidConfigID); | 706 DCHECK_NE(config_.id(), ProxyConfig::kInvalidConfigID); |
631 | 707 |
632 // If it was impossible to fetch or parse the PAC script, we cannot complete | 708 // If it was impossible to fetch or parse the PAC script, we cannot complete |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1104 OnCompletion(result_); | 1180 OnCompletion(result_); |
1105 } | 1181 } |
1106 } | 1182 } |
1107 | 1183 |
1108 void SyncProxyServiceHelper::OnCompletion(int rv) { | 1184 void SyncProxyServiceHelper::OnCompletion(int rv) { |
1109 result_ = rv; | 1185 result_ = rv; |
1110 event_.Signal(); | 1186 event_.Signal(); |
1111 } | 1187 } |
1112 | 1188 |
1113 } // namespace net | 1189 } // namespace net |
OLD | NEW |