blob: 5b7a3c57210d04d0b0a4b96d7dad2cf69b078ef7 [file]
// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/network/proxy_checking_host_resolver_request.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "net/base/net_errors.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/url_request/url_request_context.h"
#include "services/network/network_context.h"
namespace network {
ProxyCheckingHostResolverRequest::ProxyCheckingHostResolverRequest(
NetworkContext* network_context,
mojom::HostResolverHostPtr host,
const net::NetworkAnonymizationKey& network_anonymization_key,
mojom::ResolveHostParametersPtr parameters,
mojo::PendingRemote<mojom::ResolveHostClient> response_client)
: network_context_(network_context),
host_(std::move(host)),
network_anonymization_key_(network_anonymization_key),
parameters_(std::move(parameters)),
response_client_(std::move(response_client)) {
CHECK(parameters_);
// direct_only false to prevent infinite recursion on ResolveHost.
parameters_->direct_only = false;
}
ProxyCheckingHostResolverRequest::~ProxyCheckingHostResolverRequest() {
if (request_) {
int error = net::ERR_ABORTED;
response_client_->OnComplete(error, net::ResolveErrorInfo(error),
/*resolved_addresses=*/net::AddressList(),
/*alternative_endpoints=*/{});
}
}
void ProxyCheckingHostResolverRequest::Start(const GURL& url) {
CHECK(response_client_.is_connected());
response_client_.set_disconnect_handler(base::BindOnce(
&ProxyCheckingHostResolverRequest::DestroySelf, base::Unretained(this)));
int result =
network_context_->url_request_context()
->proxy_resolution_service()
->ResolveProxy(
url, std::string(), network_anonymization_key_,
net::handles::kInvalidNetworkHandle, &proxy_info_,
base::BindOnce(
&ProxyCheckingHostResolverRequest::OnResolveComplete,
base::Unretained(this)),
&request_, net::NetLogWithSource(), net::DEFAULT_PRIORITY);
if (result != net::ERR_IO_PENDING) {
OnResolveComplete(result);
}
}
void ProxyCheckingHostResolverRequest::OnResolveComplete(int result) {
CHECK(response_client_.is_connected());
response_client_.set_disconnect_handler(base::OnceClosure());
if (result == net::OK && !proxy_info_.is_direct()) {
int error = net::ERR_DNS_DIRECT_ONLY;
response_client_->OnComplete(error, net::ResolveErrorInfo(error),
/*resolved_addresses=*/net::AddressList(),
/*alternative_endpoints=*/{});
} else {
// Note we fail open, resolving host if proxy resolution failed.
network_context_->ResolveHost(std::move(host_), network_anonymization_key_,
std::move(parameters_),
response_client_.Unbind());
}
DestroySelf();
}
void ProxyCheckingHostResolverRequest::DestroySelf() {
request_.reset();
network_context_->OnProxyCheckingHostResolverRequestComplete(this);
}
} // namespace network