blob: 6fa40d787581096864db149cf69881b5dc734393 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_SERVING_HANDLE_H_
#define CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_SERVING_HANDLE_H_
#include "base/memory/weak_ptr.h"
#include "content/browser/preloading/prefetch/prefetch_streaming_url_loader_common_types.h"
#include "content/common/content_export.h"
class GURL;
namespace content {
class PrefetchContainer;
class PrefetchNetworkContext;
class PrefetchResponseReader;
class PrefetchSingleRedirectHop;
class ServiceWorkerClient;
enum class PrefetchProbeResult;
enum class PrefetchServableState;
enum class PrefetchStatus;
// A `PrefetchServingHandle` represents the current state of serving
// for a `PrefetchContainer`. The `PrefetchServingHandle` methods all
// operate on the currently *serving* `PrefetchSingleRedirectHop`,
// which is the element in |PrefetchContainer::redirect_chain()| at index
// |index_redirect_chain_to_serve_|.
//
// This works like `base::WeakPtr<PrefetchContainer>` plus additional states,
// so check that the reader is valid (e.g. `if (reader)`) before calling other
// methods (except for `Clone()`).
class CONTENT_EXPORT PrefetchServingHandle final {
public:
PrefetchServingHandle();
PrefetchServingHandle(base::WeakPtr<PrefetchContainer> prefetch_container,
size_t index_redirect_chain_to_serve);
PrefetchServingHandle(const PrefetchServingHandle&) = delete;
PrefetchServingHandle& operator=(const PrefetchServingHandle&) = delete;
PrefetchServingHandle(PrefetchServingHandle&&);
PrefetchServingHandle& operator=(PrefetchServingHandle&&);
~PrefetchServingHandle();
PrefetchContainer* GetPrefetchContainer() const {
return prefetch_container_.get();
}
PrefetchServingHandle Clone() const;
// Returns true if `this` is valid.
// Do not call methods below if false.
explicit operator bool() const { return GetPrefetchContainer(); }
// Methods redirecting to `GetPrefetchContainer()`.
PrefetchServableState GetServableState(
base::TimeDelta cacheable_duration) const;
bool HasPrefetchStatus() const;
PrefetchStatus GetPrefetchStatus() const;
// Returns whether `this` reached the end. If true, the methods below
// shouldn't be called, because the current `SingleRedirectHop` doesn't exist.
bool IsEnd() const;
// Whether or not an isolated network context is required to serve.
bool IsIsolatedNetworkContextRequiredToServe() const;
PrefetchNetworkContext* GetCurrentNetworkContextToServe() const;
bool HaveDefaultContextCookiesChanged() const;
// Before a prefetch can be served, any cookies added to the isolated
// network context must be copied over to the default network context. These
// functions are used to check and update the status of this process, as
// well as record metrics about how long this process takes.
bool HasIsolatedCookieCopyStarted() const;
bool IsIsolatedCookieCopyInProgress() const;
void OnIsolatedCookieCopyStart() const;
void OnIsolatedCookiesReadCompleteAndWriteStart() const;
void OnIsolatedCookieCopyComplete() const;
void OnInterceptorCheckCookieCopy() const;
void SetOnCookieCopyCompleteCallback(base::OnceClosure callback) const;
// Called with the result of the probe. If the probing feature is enabled,
// then a probe must complete successfully before the prefetch can be
// served.
void OnPrefetchProbeResult(PrefetchProbeResult probe_result) const;
// Checks if the given URL matches the the URL that can be served next.
bool DoesCurrentURLToServeMatch(const GURL& url) const;
// Returns the URL that can be served next.
const GURL& GetCurrentURLToServe() const;
// Gets the current PrefetchResponseReader.
base::WeakPtr<PrefetchResponseReader>
GetCurrentResponseReaderToServeForTesting();
// Called when one element of |redirect_chain_| is served and the next
// element can now be served.
void AdvanceCurrentURLToServe() { index_redirect_chain_to_serve_++; }
// See the comment for `PrefetchResponseReader::CreateRequestHandler()`.
std::pair<PrefetchRequestHandler, base::WeakPtr<ServiceWorkerClient>>
CreateRequestHandler();
// See the corresponding functions on `PrefetchResponseReader`.
// These apply to the current `SingleRedirectHop` (and so, may change as the
// prefetch advances through a redirect change).
bool VariesOnCookieIndices() const;
bool MatchesCookieIndices(
base::span<const std::pair<std::string, std::string>> cookies) const;
private:
const std::vector<std::unique_ptr<PrefetchSingleRedirectHop>>&
redirect_chain() const;
// Returns the `SingleRedirectHop` to be served next.
const PrefetchSingleRedirectHop& GetCurrentSingleRedirectHopToServe() const;
base::WeakPtr<PrefetchContainer> prefetch_container_;
// The index of the element in |GetPrefetchContainer()->redirect_chain()| that
// can be served.
size_t index_redirect_chain_to_serve_ = 0;
};
} // namespace content
#endif // CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_SERVING_HANDLE_H_