Skip to content

Commit

Permalink
[NetworkService] Introduce network::SimpleHostResolver
Browse files Browse the repository at this point in the history
This CL creates a wrapper over network.mojom.HostResolver to simplify
the common resolve scenario with supplying a
resolver client and waiting for OnComplete() to be called: now the same
result can be achieved by simply passing in a callback.

Bug: 1411522
Change-Id: Ifd76e81387dfdbccd93ce80ca08bcf9ca26b6a2e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4206827
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Commit-Queue: Andrew Rayskiy <greengrape@google.com>
Cr-Commit-Position: refs/heads/main@{#1099580}
  • Loading branch information
Andrew Rayskiy authored and Chromium LUCI CQ committed Feb 1, 2023
1 parent 28efbf2 commit 57fbf43
Show file tree
Hide file tree
Showing 4 changed files with 407 additions and 0 deletions.
3 changes: 3 additions & 0 deletions services/network/public/cpp/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ component("cpp") {
"session_cookie_delete_predicate.h",
"shared_url_loader_factory.cc",
"shared_url_loader_factory.h",
"simple_host_resolver.cc",
"simple_host_resolver.h",
"simple_url_loader.cc",
"simple_url_loader.h",
"simple_url_loader_stream_consumer.h",
Expand Down Expand Up @@ -499,6 +501,7 @@ source_set("tests") {
"parsed_headers_unittest.cc",
"proxy_config_mojom_traits_unittest.cc",
"schemeful_site_mojom_traits_unittest.cc",
"simple_host_resolver_unittest.cc",
"simple_url_loader_unittest.cc",
"source_stream_to_data_pipe_unittest.cc",
"structured_headers_mojom_traits_unittest.cc",
Expand Down
87 changes: 87 additions & 0 deletions services/network/public/cpp/simple_host_resolver.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright 2023 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/public/cpp/simple_host_resolver.h"

#include "base/functional/bind.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/network_anonymization_key.h"
#include "services/network/public/cpp/resolve_host_client_base.h"
#include "services/network/public/mojom/host_resolver.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"

namespace network {

class SimpleHostResolverImpl : public SimpleHostResolver,
public ResolveHostClientBase {
public:
explicit SimpleHostResolverImpl(
mojo::PendingRemote<mojom::HostResolver> resolver)
: resolver_(std::move(resolver)) {
receivers_.set_disconnect_handler(
base::BindRepeating(&SimpleHostResolverImpl::OnReceiverDisconnected,
base::Unretained(this)));
}

void ResolveHost(
mojom::HostResolverHostPtr host,
const net::NetworkAnonymizationKey& network_anonymization_key,
mojom::ResolveHostParametersPtr optional_parameters,
ResolveHostCallback callback) override {
DCHECK(resolver_.is_bound());
mojo::PendingReceiver<mojom::ResolveHostClient> receiver;
resolver_->ResolveHost(std::move(host), network_anonymization_key,
std::move(optional_parameters),
receiver.InitWithNewPipeAndPassRemote());
receivers_.Add(this, std::move(receiver), std::move(callback));
}

uint32_t GetNumOutstandingRequestsForTesting() const override {
return receivers_.size();
}

private:
// network::ResolveHostClientBase:
void OnComplete(int result,
const net::ResolveErrorInfo& resolve_error_info,
const absl::optional<net::AddressList>& resolved_addresses,
const absl::optional<net::HostResolverEndpointResults>&
endpoint_results_with_metadata) override {
auto callback = std::move(receivers_.current_context());
receivers_.Remove(receivers_.current_receiver());
std::move(callback).Run(result, resolve_error_info, resolved_addresses,
endpoint_results_with_metadata);
}

void OnReceiverDisconnected() {
std::move(receivers_.current_context())
.Run(net::ERR_FAILED, net::ResolveErrorInfo(net::ERR_FAILED),
/*resolved_addresses=*/absl::nullopt,
/*endpoint_results_with_metadata=*/absl::nullopt);
}

mojo::Remote<mojom::HostResolver> resolver_;
mojo::ReceiverSet<mojom::ResolveHostClient,
SimpleHostResolver::ResolveHostCallback>
receivers_;
};

// static
std::unique_ptr<SimpleHostResolver> SimpleHostResolver::Create(
network::mojom::NetworkContext* network_context,
const absl::optional<net::DnsConfigOverrides>& config_overrides) {
mojo::PendingRemote<network::mojom::HostResolver> resolver;
network_context->CreateHostResolver(
config_overrides, resolver.InitWithNewPipeAndPassReceiver());
return std::make_unique<SimpleHostResolverImpl>(std::move(resolver));
}

// static
std::unique_ptr<SimpleHostResolver> SimpleHostResolver::CreateForTesting(
mojo::PendingRemote<network::mojom::HostResolver> resolver) {
return std::make_unique<SimpleHostResolverImpl>(std::move(resolver));
}

} // namespace network
91 changes: 91 additions & 0 deletions services/network/public/cpp/simple_host_resolver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SERVICES_NETWORK_PUBLIC_CPP_SIMPLE_HOST_RESOLVER_H_
#define SERVICES_NETWORK_PUBLIC_CPP_SIMPLE_HOST_RESOLVER_H_

#include "base/component_export.h"
#include "base/functional/callback_forward.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/dns/public/dns_config_overrides.h"
#include "services/network/public/mojom/host_resolver.mojom.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace net {
class AddressList;
} // namespace net

namespace network {

namespace mojom {
class NetworkContext;
} // namespace mojom

// Wraps network.mojom.HostResolver and allows it to be used with callbacks
// instead of receivers effectively eliminating the need to create custom
// resolver clients.
// * With mojom.HostResolver:
// - Create a resolver client that inherits from mojom.ResolveHostClient
// and override OnComplete() method;
// - Call mojom.HostResolver.ResolveHost();
// - Wait till OnComplete() is invoked and manually delete the client.
// * With SimpleHostResolver:
// - Call SimpleHostResolver.ResolveHost() with callback mimicking
// OnComplete() and wait for it to fire.
//
// Prefer using this class over mojom.HostResolver unless you're interested
// in OnTextResults()/OnHostnameResults() events.
//
// Deleting a SimpleHostResolver cancels outstanding resolve requests.
class COMPONENT_EXPORT(NETWORK_CPP) SimpleHostResolver {
public:
using ResolveHostCallback = base::OnceCallback<void(
int result,
const net::ResolveErrorInfo& resolve_error_info,
const absl::optional<net::AddressList>& resolved_addresses,
const absl::optional<net::HostResolverEndpointResults>&
endpoint_results_with_metadata)>;

// Creates a SimpleHostResolver from the given |network_context| and
// |config_overrides|. |network_context| must outlive SimpleHostResolver.
static std::unique_ptr<SimpleHostResolver> Create(
mojom::NetworkContext* network_context,
const absl::optional<net::DnsConfigOverrides>& config_overrides = {});

// Creates a SimpleHostResolver that uses the provided |resolver| for host
// resolving.
static std::unique_ptr<SimpleHostResolver> CreateForTesting(
mojo::PendingRemote<mojom::HostResolver> resolver);

virtual ~SimpleHostResolver() = default;

SimpleHostResolver(const SimpleHostResolver&) = delete;
SimpleHostResolver& operator=(const SimpleHostResolver&) = delete;

// Mimics mojom.HostResolver.ResolveHost(), but dumps the result into the
// provided |callback| instead of invoking OnComplete() on a resolver client.
//
// See mojom.ResolveHostClient.OnComplete() for more information on response
// format and callback parameter descriptions.
//
// It's safe to supply |callback| bound via Unretained() since |callback| can
// only be run while |this| is alive (destroying |this| cancels all pending
// callbacks).
// If mojo pipe breaks |callback| will be invoked with net::ERR_FAILED.
virtual void ResolveHost(
mojom::HostResolverHostPtr host,
const net::NetworkAnonymizationKey& network_anonymization_key,
mojom::ResolveHostParametersPtr optional_parameters,
ResolveHostCallback callback) = 0;

// Tells how many requests there are in flight.
virtual uint32_t GetNumOutstandingRequestsForTesting() const = 0;

protected:
SimpleHostResolver() = default;
};

} // namespace network

#endif // SERVICES_NETWORK_PUBLIC_CPP_SIMPLE_HOST_RESOLVER_H_

0 comments on commit 57fbf43

Please sign in to comment.