configured_proxy_resolution_request.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/proxy_resolution/configured_proxy_resolution_request.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/callback_helpers.h"
  8. #include "net/base/net_errors.h"
  9. #include "net/log/net_log_event_type.h"
  10. #include "net/proxy_resolution/configured_proxy_resolution_service.h"
  11. #include "net/proxy_resolution/proxy_info.h"
  12. namespace net {
  13. ConfiguredProxyResolutionRequest::ConfiguredProxyResolutionRequest(
  14. ConfiguredProxyResolutionService* service,
  15. const GURL& url,
  16. const std::string& method,
  17. const NetworkIsolationKey& network_isolation_key,
  18. ProxyInfo* results,
  19. CompletionOnceCallback user_callback,
  20. const NetLogWithSource& net_log)
  21. : service_(service),
  22. user_callback_(std::move(user_callback)),
  23. results_(results),
  24. url_(url),
  25. method_(method),
  26. network_isolation_key_(network_isolation_key),
  27. net_log_(net_log),
  28. creation_time_(base::TimeTicks::Now()) {
  29. DCHECK(!user_callback_.is_null());
  30. }
  31. ConfiguredProxyResolutionRequest::~ConfiguredProxyResolutionRequest() {
  32. if (service_) {
  33. service_->RemovePendingRequest(this);
  34. net_log_.AddEvent(NetLogEventType::CANCELLED);
  35. if (is_started())
  36. CancelResolveJob();
  37. // This should be emitted last, after any message |CancelResolveJob()| may
  38. // trigger.
  39. net_log_.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
  40. }
  41. }
  42. // Starts the resolve proxy request.
  43. int ConfiguredProxyResolutionRequest::Start() {
  44. DCHECK(!was_completed());
  45. DCHECK(!is_started());
  46. DCHECK(service_->config_);
  47. traffic_annotation_ = MutableNetworkTrafficAnnotationTag(
  48. service_->config_->traffic_annotation());
  49. if (service_->ApplyPacBypassRules(url_, results_))
  50. return OK;
  51. return service_->GetProxyResolver()->GetProxyForURL(
  52. url_, network_isolation_key_, results_,
  53. base::BindOnce(&ConfiguredProxyResolutionRequest::QueryComplete,
  54. base::Unretained(this)),
  55. &resolve_job_, net_log_);
  56. }
  57. void ConfiguredProxyResolutionRequest::
  58. StartAndCompleteCheckingForSynchronous() {
  59. int rv = service_->TryToCompleteSynchronously(url_, results_);
  60. if (rv == ERR_IO_PENDING)
  61. rv = Start();
  62. if (rv != ERR_IO_PENDING)
  63. QueryComplete(rv);
  64. }
  65. void ConfiguredProxyResolutionRequest::CancelResolveJob() {
  66. DCHECK(is_started());
  67. // The request may already be running in the resolver.
  68. resolve_job_.reset();
  69. DCHECK(!is_started());
  70. }
  71. int ConfiguredProxyResolutionRequest::QueryDidComplete(int result_code) {
  72. DCHECK(!was_completed());
  73. // Clear |resolve_job_| so is_started() returns false while
  74. // DidFinishResolvingProxy() runs.
  75. resolve_job_.reset();
  76. // Note that DidFinishResolvingProxy might modify |results_|.
  77. int rv = service_->DidFinishResolvingProxy(url_, method_, results_,
  78. result_code, net_log_);
  79. // Make a note in the results which configuration was in use at the
  80. // time of the resolve.
  81. results_->set_proxy_resolve_start_time(creation_time_);
  82. results_->set_proxy_resolve_end_time(base::TimeTicks::Now());
  83. // If annotation is not already set, e.g. through TryToCompleteSynchronously
  84. // function, use in-progress-resolve annotation.
  85. if (!results_->traffic_annotation().is_valid())
  86. results_->set_traffic_annotation(traffic_annotation_);
  87. // If proxy is set without error, ensure that an annotation is provided.
  88. if (result_code != ERR_ABORTED && !rv)
  89. DCHECK(results_->traffic_annotation().is_valid());
  90. // Reset the state associated with in-progress-resolve.
  91. traffic_annotation_.reset();
  92. return rv;
  93. }
  94. int ConfiguredProxyResolutionRequest::QueryDidCompleteSynchronously(
  95. int result_code) {
  96. int rv = QueryDidComplete(result_code);
  97. service_ = nullptr;
  98. return rv;
  99. }
  100. LoadState ConfiguredProxyResolutionRequest::GetLoadState() const {
  101. LoadState load_state = LOAD_STATE_IDLE;
  102. if (service_ && service_->GetLoadStateIfAvailable(&load_state))
  103. return load_state;
  104. if (is_started())
  105. return resolve_job_->GetLoadState();
  106. return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
  107. }
  108. // Callback for when the ProxyResolver request has completed.
  109. void ConfiguredProxyResolutionRequest::QueryComplete(int result_code) {
  110. result_code = QueryDidComplete(result_code);
  111. CompletionOnceCallback callback = std::move(user_callback_);
  112. service_->RemovePendingRequest(this);
  113. service_ = nullptr;
  114. user_callback_.Reset();
  115. std::move(callback).Run(result_code);
  116. }
  117. } // namespace net