147 lines
4.5 KiB
C++
147 lines
4.5 KiB
C++
// Copyright 2020 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "net/proxy_resolution/configured_proxy_resolution_request.h"
|
|
|
|
#include <utility>
|
|
|
|
#include "base/functional/bind.h"
|
|
#include "base/functional/callback_helpers.h"
|
|
#include "net/base/net_errors.h"
|
|
#include "net/log/net_log_event_type.h"
|
|
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
|
|
#include "net/proxy_resolution/proxy_info.h"
|
|
|
|
namespace net {
|
|
|
|
ConfiguredProxyResolutionRequest::ConfiguredProxyResolutionRequest(
|
|
ConfiguredProxyResolutionService* service,
|
|
const GURL& url,
|
|
const std::string& method,
|
|
const NetworkAnonymizationKey& network_anonymization_key,
|
|
ProxyInfo* results,
|
|
CompletionOnceCallback user_callback,
|
|
const NetLogWithSource& net_log)
|
|
: service_(service),
|
|
user_callback_(std::move(user_callback)),
|
|
results_(results),
|
|
url_(url),
|
|
method_(method),
|
|
network_anonymization_key_(network_anonymization_key),
|
|
net_log_(net_log),
|
|
creation_time_(base::TimeTicks::Now()) {
|
|
DCHECK(!user_callback_.is_null());
|
|
}
|
|
|
|
ConfiguredProxyResolutionRequest::~ConfiguredProxyResolutionRequest() {
|
|
if (service_) {
|
|
service_->RemovePendingRequest(this);
|
|
net_log_.AddEvent(NetLogEventType::CANCELLED);
|
|
|
|
if (is_started())
|
|
CancelResolveJob();
|
|
|
|
// This should be emitted last, after any message |CancelResolveJob()| may
|
|
// trigger.
|
|
net_log_.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
|
|
}
|
|
}
|
|
|
|
// Starts the resolve proxy request.
|
|
int ConfiguredProxyResolutionRequest::Start() {
|
|
DCHECK(!was_completed());
|
|
DCHECK(!is_started());
|
|
|
|
DCHECK(service_->config_);
|
|
traffic_annotation_ = MutableNetworkTrafficAnnotationTag(
|
|
service_->config_->traffic_annotation());
|
|
|
|
if (service_->ApplyPacBypassRules(url_, results_))
|
|
return OK;
|
|
|
|
return service_->GetProxyResolver()->GetProxyForURL(
|
|
url_, network_anonymization_key_, results_,
|
|
base::BindOnce(&ConfiguredProxyResolutionRequest::QueryComplete,
|
|
base::Unretained(this)),
|
|
&resolve_job_, net_log_);
|
|
}
|
|
|
|
void ConfiguredProxyResolutionRequest::
|
|
StartAndCompleteCheckingForSynchronous() {
|
|
int rv = service_->TryToCompleteSynchronously(url_, results_);
|
|
if (rv == ERR_IO_PENDING)
|
|
rv = Start();
|
|
if (rv != ERR_IO_PENDING)
|
|
QueryComplete(rv);
|
|
}
|
|
|
|
void ConfiguredProxyResolutionRequest::CancelResolveJob() {
|
|
DCHECK(is_started());
|
|
// The request may already be running in the resolver.
|
|
resolve_job_.reset();
|
|
DCHECK(!is_started());
|
|
}
|
|
|
|
int ConfiguredProxyResolutionRequest::QueryDidComplete(int result_code) {
|
|
DCHECK(!was_completed());
|
|
|
|
// Clear |resolve_job_| so is_started() returns false while
|
|
// DidFinishResolvingProxy() runs.
|
|
resolve_job_.reset();
|
|
|
|
// Note that DidFinishResolvingProxy might modify |results_|.
|
|
int rv = service_->DidFinishResolvingProxy(url_, method_, results_,
|
|
result_code, net_log_);
|
|
|
|
// Make a note in the results which configuration was in use at the
|
|
// time of the resolve.
|
|
results_->set_proxy_resolve_start_time(creation_time_);
|
|
results_->set_proxy_resolve_end_time(base::TimeTicks::Now());
|
|
|
|
// If annotation is not already set, e.g. through TryToCompleteSynchronously
|
|
// function, use in-progress-resolve annotation.
|
|
if (!results_->traffic_annotation().is_valid())
|
|
results_->set_traffic_annotation(traffic_annotation_);
|
|
|
|
// If proxy is set without error, ensure that an annotation is provided.
|
|
if (result_code != ERR_ABORTED && !rv)
|
|
DCHECK(results_->traffic_annotation().is_valid());
|
|
|
|
// Reset the state associated with in-progress-resolve.
|
|
traffic_annotation_.reset();
|
|
|
|
return rv;
|
|
}
|
|
|
|
int ConfiguredProxyResolutionRequest::QueryDidCompleteSynchronously(
|
|
int result_code) {
|
|
int rv = QueryDidComplete(result_code);
|
|
service_ = nullptr;
|
|
return rv;
|
|
}
|
|
|
|
LoadState ConfiguredProxyResolutionRequest::GetLoadState() const {
|
|
LoadState load_state = LOAD_STATE_IDLE;
|
|
if (service_ && service_->GetLoadStateIfAvailable(&load_state))
|
|
return load_state;
|
|
|
|
if (is_started())
|
|
return resolve_job_->GetLoadState();
|
|
return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
|
|
}
|
|
|
|
// Callback for when the ProxyResolver request has completed.
|
|
void ConfiguredProxyResolutionRequest::QueryComplete(int result_code) {
|
|
result_code = QueryDidComplete(result_code);
|
|
|
|
CompletionOnceCallback callback = std::move(user_callback_);
|
|
|
|
service_->RemovePendingRequest(this);
|
|
service_ = nullptr;
|
|
user_callback_.Reset();
|
|
std::move(callback).Run(result_code);
|
|
}
|
|
|
|
} // namespace net
|