Add RetryOptions to blink and plumb with mojo
This CL adds the RetryOptions idl and FetchRetryOptions mojom, which allows JS-configured fetch retry policies. This value will be used in crrev.com/c/6471874 which implements the actual retry logic. Explainer: https://github.com/explainers-by-googlers/fetch-retry Bug: 417930271 Change-Id: I17b40c4c887e1d680527dc02fb583d5c264ced46 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6490773 Reviewed-by: Kouhei Ueno <kouhei@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Reviewed-by: Takashi Toyoshima <toyoshim@chromium.org> Commit-Queue: Rakina Zata Amni <rakina@chromium.org> Cr-Commit-Position: refs/heads/main@{#1460675}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
19a26c304c
commit
e8d806fd94
@ -123,7 +123,8 @@ namespace {
|
||||
DO_FIELD(socket_tag) __VA_ARGS__ \
|
||||
DO_FIELD(keepalive_token) __VA_ARGS__ \
|
||||
DO_FIELD(allows_device_bound_session_registration) __VA_ARGS__ \
|
||||
DO_FIELD(permissions_policy)
|
||||
DO_FIELD(permissions_policy) __VA_ARGS__ \
|
||||
DO_FIELD(fetch_retry_options)
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
@ -248,6 +248,18 @@ component("integrity_policy") {
|
||||
defines = [ "IS_NETWORK_CPP_INTEGRITY_POLICY_IMPL" ]
|
||||
}
|
||||
|
||||
component("fetch_retry_options") {
|
||||
sources = [
|
||||
"fetch_retry_options.cc",
|
||||
"fetch_retry_options.h",
|
||||
]
|
||||
deps = [
|
||||
"//net",
|
||||
"//services/network/public/mojom:url_loader_base_shared",
|
||||
]
|
||||
defines = [ "IS_NETWORK_CPP_FETCH_RETRY_OPTIONS_IMPL" ]
|
||||
}
|
||||
|
||||
component("cookies_mojom_support") {
|
||||
sources = [
|
||||
"cookie_manager_shared_mojom_traits.cc",
|
||||
@ -597,6 +609,7 @@ component("cpp_base") {
|
||||
":crash_keys",
|
||||
":cross_origin_embedder_policy",
|
||||
":document_isolation_policy",
|
||||
":fetch_retry_options",
|
||||
":integrity_policy",
|
||||
":ip_address_mojom_support",
|
||||
":network_param_mojom_support",
|
||||
|
20
services/network/public/cpp/fetch_retry_options.cc
Normal file
20
services/network/public/cpp/fetch_retry_options.cc
Normal file
@ -0,0 +1,20 @@
|
||||
// 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.
|
||||
|
||||
#include "services/network/public/cpp/fetch_retry_options.h"
|
||||
|
||||
namespace network {
|
||||
|
||||
FetchRetryOptions::FetchRetryOptions() = default;
|
||||
FetchRetryOptions::~FetchRetryOptions() = default;
|
||||
|
||||
FetchRetryOptions::FetchRetryOptions(FetchRetryOptions&&) = default;
|
||||
FetchRetryOptions& FetchRetryOptions::operator=(FetchRetryOptions&&) = default;
|
||||
|
||||
FetchRetryOptions::FetchRetryOptions(const FetchRetryOptions&) = default;
|
||||
FetchRetryOptions& FetchRetryOptions::operator=(const FetchRetryOptions&) =
|
||||
default;
|
||||
bool FetchRetryOptions::operator==(const FetchRetryOptions&) const = default;
|
||||
|
||||
} // namespace network
|
43
services/network/public/cpp/fetch_retry_options.h
Normal file
43
services/network/public/cpp/fetch_retry_options.h
Normal file
@ -0,0 +1,43 @@
|
||||
// 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 SERVICES_NETWORK_PUBLIC_CPP_FETCH_RETRY_OPTIONS_H_
|
||||
#define SERVICES_NETWORK_PUBLIC_CPP_FETCH_RETRY_OPTIONS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "services/network/public/mojom/fetch_retry_options.mojom-shared.h"
|
||||
|
||||
namespace network {
|
||||
|
||||
// This implements a data structure holding the policy configurations for fetch
|
||||
// retry feature.
|
||||
//
|
||||
// This struct is needed so that we can pass the same object when plumbing.
|
||||
struct COMPONENT_EXPORT(NETWORK_CPP_FETCH_RETRY_OPTIONS) FetchRetryOptions {
|
||||
FetchRetryOptions();
|
||||
~FetchRetryOptions();
|
||||
|
||||
FetchRetryOptions(FetchRetryOptions&&);
|
||||
FetchRetryOptions& operator=(FetchRetryOptions&&);
|
||||
|
||||
FetchRetryOptions(const FetchRetryOptions&);
|
||||
FetchRetryOptions& operator=(const FetchRetryOptions&);
|
||||
|
||||
bool operator==(const FetchRetryOptions&) const;
|
||||
|
||||
uint32_t max_attempts = 0;
|
||||
std::optional<base::TimeDelta> initial_delay;
|
||||
std::optional<double> backoff_factor;
|
||||
std::optional<base::TimeDelta> max_age;
|
||||
bool retry_after_unload = false;
|
||||
bool retry_non_idempotent = false;
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
|
||||
#endif // SERVICES_NETWORK_PUBLIC_CPP_FETCH_RETRY_OPTIONS_H_
|
@ -349,7 +349,8 @@ bool ResourceRequest::EqualsForTesting(const ResourceRequest& request) const {
|
||||
socket_tag == request.socket_tag &&
|
||||
allows_device_bound_session_registration ==
|
||||
request.allows_device_bound_session_registration &&
|
||||
permissions_policy == request.permissions_policy;
|
||||
permissions_policy == request.permissions_policy &&
|
||||
fetch_retry_options == request.fetch_retry_options;
|
||||
}
|
||||
|
||||
bool ResourceRequest::SendsCookies() const {
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "net/socket/socket_tag.h"
|
||||
#include "net/storage_access_api/status.h"
|
||||
#include "net/url_request/referrer_policy.h"
|
||||
#include "services/network/public/cpp/fetch_retry_options.h"
|
||||
#include "services/network/public/cpp/optional_trust_token_params.h"
|
||||
#include "services/network/public/cpp/permissions_policy/permissions_policy.h"
|
||||
#include "services/network/public/cpp/resource_request_body.h"
|
||||
@ -252,6 +253,8 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) ResourceRequest {
|
||||
bool allows_device_bound_session_registration = false;
|
||||
|
||||
std::optional<network::PermissionsPolicy> permissions_policy;
|
||||
|
||||
std::optional<network::FetchRetryOptions> fetch_retry_options;
|
||||
};
|
||||
// LINT.ThenChange(//services/network/prefetch_matches.cc)
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "services/network/public/mojom/data_pipe_getter.mojom.h"
|
||||
#include "services/network/public/mojom/device_bound_sessions.mojom.h"
|
||||
#include "services/network/public/mojom/devtools_observer.mojom.h"
|
||||
#include "services/network/public/mojom/fetch_retry_options.mojom.h"
|
||||
#include "services/network/public/mojom/ip_address_space.mojom.h"
|
||||
#include "services/network/public/mojom/trust_token_access_observer.mojom.h"
|
||||
#include "services/network/public/mojom/trust_tokens.mojom.h"
|
||||
@ -139,7 +140,8 @@ bool StructTraits<
|
||||
!data.ReadKeepaliveToken(&out->keepalive_token) ||
|
||||
!data.ReadStorageAccessApiStatus(&out->storage_access_api_status) ||
|
||||
!data.ReadSocketTag(&out->socket_tag) ||
|
||||
!data.ReadPermissionsPolicy(&out->permissions_policy)) {
|
||||
!data.ReadPermissionsPolicy(&out->permissions_policy) ||
|
||||
!data.ReadFetchRetryOptions(&out->fetch_retry_options)) {
|
||||
// Note that data.ReadTrustTokenParams is temporarily handled below.
|
||||
return false;
|
||||
}
|
||||
@ -314,4 +316,19 @@ bool StructTraits<network::mojom::SocketTagDataView, net::SocketTag>::Read(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StructTraits<network::mojom::FetchRetryOptionsDataView,
|
||||
network::FetchRetryOptions>::
|
||||
Read(network::mojom::FetchRetryOptionsDataView data,
|
||||
FetchRetryOptions* out) {
|
||||
out->max_attempts = data.max_attempts();
|
||||
if (!data.ReadInitialDelay(&out->initial_delay) ||
|
||||
!data.ReadMaxAge(&out->max_age)) {
|
||||
return false;
|
||||
}
|
||||
out->backoff_factor = data.backoff_factor();
|
||||
out->retry_after_unload = data.retry_after_unload();
|
||||
out->retry_non_idempotent = data.retry_non_idempotent();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mojo
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "services/network/public/mojom/data_pipe_getter.mojom.h"
|
||||
#include "services/network/public/mojom/device_bound_sessions.mojom-forward.h"
|
||||
#include "services/network/public/mojom/devtools_observer.mojom-forward.h"
|
||||
#include "services/network/public/mojom/fetch_retry_options.mojom.h"
|
||||
#include "services/network/public/mojom/ip_address_space.mojom-forward.h"
|
||||
#include "services/network/public/mojom/trust_token_access_observer.mojom-forward.h"
|
||||
#include "services/network/public/mojom/trust_tokens.mojom-forward.h"
|
||||
@ -424,6 +425,10 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE)
|
||||
const network::ResourceRequest& request) {
|
||||
return request.permissions_policy;
|
||||
}
|
||||
static const std::optional<network::FetchRetryOptions>& fetch_retry_options(
|
||||
const network::ResourceRequest& request) {
|
||||
return request.fetch_retry_options;
|
||||
}
|
||||
|
||||
static bool Read(network::mojom::URLRequestDataView data,
|
||||
network::ResourceRequest* out);
|
||||
@ -570,6 +575,38 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE)
|
||||
static bool Read(network::mojom::SocketTagDataView data, net::SocketTag* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct COMPONENT_EXPORT(NETWORK_CPP_BASE)
|
||||
StructTraits<network::mojom::FetchRetryOptionsDataView,
|
||||
network::FetchRetryOptions> {
|
||||
using FetchRetryOptions = network::FetchRetryOptions;
|
||||
|
||||
static uint32_t max_attempts(const FetchRetryOptions& options) {
|
||||
return options.max_attempts;
|
||||
}
|
||||
static std::optional<base::TimeDelta> initial_delay(
|
||||
const FetchRetryOptions& options) {
|
||||
return options.initial_delay;
|
||||
}
|
||||
static std::optional<base::TimeDelta> max_age(
|
||||
const FetchRetryOptions& options) {
|
||||
return options.max_age;
|
||||
}
|
||||
static const std::optional<double>& backoff_factor(
|
||||
const FetchRetryOptions& options) {
|
||||
return options.backoff_factor;
|
||||
}
|
||||
static bool retry_after_unload(const FetchRetryOptions& options) {
|
||||
return options.retry_after_unload;
|
||||
}
|
||||
static bool retry_non_idempotent(const FetchRetryOptions& options) {
|
||||
return options.retry_non_idempotent;
|
||||
}
|
||||
|
||||
static bool Read(network::mojom::FetchRetryOptionsDataView data,
|
||||
network::FetchRetryOptions* out);
|
||||
};
|
||||
|
||||
} // namespace mojo
|
||||
|
||||
#endif // SERVICES_NETWORK_PUBLIC_CPP_URL_REQUEST_MOJOM_TRAITS_H_
|
||||
|
@ -613,6 +613,7 @@ mojom("url_loader_base") {
|
||||
"early_hints.mojom",
|
||||
"encoded_body_length.mojom",
|
||||
"fetch_api.mojom",
|
||||
"fetch_retry_options.mojom",
|
||||
"http_raw_headers.mojom",
|
||||
"http_request_headers.mojom",
|
||||
"ip_address_space.mojom",
|
||||
|
18
services/network/public/mojom/fetch_retry_options.mojom
Normal file
18
services/network/public/mojom/fetch_retry_options.mojom
Normal file
@ -0,0 +1,18 @@
|
||||
// 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.
|
||||
|
||||
module network.mojom;
|
||||
|
||||
import "mojo/public/mojom/base/time.mojom";
|
||||
|
||||
// See third_party/blink/renderer/core/fetch/retry_options.idl for details of
|
||||
// each member.
|
||||
struct FetchRetryOptions {
|
||||
uint32 max_attempts;
|
||||
mojo_base.mojom.TimeDelta? initial_delay;
|
||||
double? backoff_factor;
|
||||
mojo_base.mojom.TimeDelta? max_age;
|
||||
bool retry_after_unload = false;
|
||||
bool retry_non_idempotent = false;
|
||||
};
|
@ -19,6 +19,7 @@ import "services/network/public/mojom/data_pipe_getter.mojom";
|
||||
import "services/network/public/mojom/device_bound_sessions.mojom";
|
||||
import "services/network/public/mojom/devtools_observer.mojom";
|
||||
import "services/network/public/mojom/fetch_api.mojom";
|
||||
import "services/network/public/mojom/fetch_retry_options.mojom";
|
||||
import "services/network/public/mojom/http_raw_headers.mojom";
|
||||
import "services/network/public/mojom/http_request_headers.mojom";
|
||||
import "services/network/public/mojom/ip_address_space.mojom";
|
||||
@ -611,6 +612,10 @@ struct URLRequest {
|
||||
// If it's nullopt then the request's initiator didn't set the permissions
|
||||
// policy. Example: https://crrev.com/c/6295903
|
||||
network.mojom.PermissionsPolicy? permissions_policy;
|
||||
|
||||
// The policies to be used when retrying a fetch. Will only be set on fetch
|
||||
// requests who specified its RetryOptions.
|
||||
network.mojom.FetchRetryOptions? fetch_retry_options;
|
||||
};
|
||||
|
||||
// URLRequestBody represents body (i.e. upload data) of a HTTP request.
|
||||
|
@ -396,6 +396,8 @@ generated_dictionary_sources_in_core = [
|
||||
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_options.h",
|
||||
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_response_init.cc",
|
||||
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_response_init.h",
|
||||
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_retry_options.cc",
|
||||
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_retry_options.h",
|
||||
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_sanitizer_attribute_namespace.cc",
|
||||
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_sanitizer_attribute_namespace.h",
|
||||
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_sanitizer_config.cc",
|
||||
|
@ -277,6 +277,7 @@ static_idl_files_in_core = [
|
||||
"//third_party/blink/renderer/core/fetch/request_init.idl",
|
||||
"//third_party/blink/renderer/core/fetch/response.idl",
|
||||
"//third_party/blink/renderer/core/fetch/response_init.idl",
|
||||
"//third_party/blink/renderer/core/fetch/retry_options.idl",
|
||||
"//third_party/blink/renderer/core/fetch/window_fetch.idl",
|
||||
"//third_party/blink/renderer/core/fetch/worker_fetch.idl",
|
||||
"//third_party/blink/renderer/core/fileapi/blob.idl",
|
||||
|
@ -1159,6 +1159,10 @@ void FetchLoaderBase::PerformHTTPFetch(ExceptionState& exception_state) {
|
||||
UseCounter::Count(execution_context_, mojom::WebFeature::kFetchKeepalive);
|
||||
}
|
||||
|
||||
if (fetch_request_data_->HasRetryOptions()) {
|
||||
request.SetFetchRetryOptions(fetch_request_data_->RetryOptions().value());
|
||||
}
|
||||
|
||||
request.SetBrowsingTopics(fetch_request_data_->BrowsingTopics());
|
||||
request.SetAdAuctionHeaders(fetch_request_data_->AdAuctionHeaders());
|
||||
request.SetAttributionReportingEligibility(
|
||||
|
@ -247,6 +247,7 @@ FetchRequestData* FetchRequestData::CloneExceptBody() {
|
||||
request->attribution_reporting_support_ = attribution_reporting_support_;
|
||||
request->service_worker_race_network_request_token_ =
|
||||
service_worker_race_network_request_token_;
|
||||
request->retry_options_ = retry_options_;
|
||||
return request;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/unguessable_token.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "services/network/public/cpp/fetch_retry_options.h"
|
||||
#include "services/network/public/mojom/attribution.mojom-blink.h"
|
||||
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
|
||||
#include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h"
|
||||
@ -205,6 +206,16 @@ class CORE_EXPORT FetchRequestData final
|
||||
service_worker_race_network_request_token_ = token;
|
||||
}
|
||||
|
||||
bool HasRetryOptions() const { return retry_options_.has_value(); }
|
||||
|
||||
const std::optional<network::FetchRetryOptions>& RetryOptions() const {
|
||||
return retry_options_;
|
||||
}
|
||||
|
||||
void SetRetryOptions(network::FetchRetryOptions retry_options) {
|
||||
retry_options_ = retry_options;
|
||||
}
|
||||
|
||||
void Trace(Visitor*) const;
|
||||
|
||||
private:
|
||||
@ -260,6 +271,7 @@ class CORE_EXPORT FetchRequestData final
|
||||
network::mojom::AttributionReportingEligibility::kUnset;
|
||||
network::mojom::AttributionSupport attribution_reporting_support_ =
|
||||
network::mojom::AttributionSupport::kUnset;
|
||||
std::optional<network::FetchRetryOptions> retry_options_;
|
||||
// A specific factory that should be used for this request instead of whatever
|
||||
// the system would otherwise decide to use to load this request.
|
||||
// Currently used for blob: URLs, to ensure they can still be loaded even if
|
||||
|
26
third_party/blink/renderer/core/fetch/request.cc
vendored
26
third_party/blink/renderer/core/fetch/request.cc
vendored
@ -30,6 +30,7 @@
|
||||
#include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/v8_request_mode.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/v8_request_redirect.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/v8_retry_options.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/v8_union_request_usvstring.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/v8_url_search_params.h"
|
||||
#include "third_party/blink/renderer/core/dom/abort_signal.h"
|
||||
@ -182,6 +183,9 @@ FetchRequestData* CreateCopyOfFetchRequestDataForFetch(
|
||||
request->SetAttributionReportingSupport(original->AttributionSupport());
|
||||
request->SetServiceWorkerRaceNetworkRequestToken(
|
||||
original->ServiceWorkerRaceNetworkRequestToken());
|
||||
if (original->HasRetryOptions()) {
|
||||
request->SetRetryOptions(original->RetryOptions().value());
|
||||
}
|
||||
|
||||
// When a new request is created from another the destination is always reset
|
||||
// to be `kEmpty`. In order to facilitate some later checks when a service
|
||||
@ -205,7 +209,8 @@ static bool AreAnyMembersPresent(const RequestInit* init) {
|
||||
init->hasKeepalive() || init->hasBrowsingTopics() ||
|
||||
init->hasAdAuctionHeaders() || init->hasSharedStorageWritable() ||
|
||||
init->hasPriority() || init->hasSignal() || init->hasDuplex() ||
|
||||
init->hasPrivateToken() || init->hasAttributionReporting();
|
||||
init->hasPrivateToken() || init->hasAttributionReporting() ||
|
||||
init->hasRetryOptions();
|
||||
}
|
||||
|
||||
static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
|
||||
@ -642,6 +647,25 @@ Request* Request::CreateRequestWithRequestOrString(
|
||||
if (init->hasKeepalive())
|
||||
request->SetKeepalive(init->keepalive());
|
||||
|
||||
if (init->hasRetryOptions()) {
|
||||
network::FetchRetryOptions options;
|
||||
RetryOptions* retry_options = init->retryOptions();
|
||||
options.max_attempts = retry_options->maxAttempts();
|
||||
if (retry_options->hasInitialDelay()) {
|
||||
options.initial_delay =
|
||||
base::Milliseconds(retry_options->initialDelay().value());
|
||||
}
|
||||
if (retry_options->hasBackoffFactor()) {
|
||||
options.backoff_factor = retry_options->backoffFactor();
|
||||
}
|
||||
if (retry_options->hasMaxAge()) {
|
||||
options.max_age = base::Milliseconds(retry_options->maxAge().value());
|
||||
}
|
||||
options.retry_after_unload = retry_options->retryAfterUnload();
|
||||
options.retry_non_idempotent = retry_options->retryNonIdempotent();
|
||||
request->SetRetryOptions(options);
|
||||
}
|
||||
|
||||
if (init->hasBrowsingTopics()) {
|
||||
if (!execution_context->IsSecureContext()) {
|
||||
exception_state.ThrowTypeError(
|
||||
|
@ -33,6 +33,7 @@ dictionary RequestInit {
|
||||
// because the SecureContext IDL attribute doesn't affect dictionary members.
|
||||
[RuntimeEnabled=PrivateStateTokens] PrivateToken privateToken;
|
||||
[RuntimeEnabled=AttributionReporting] AttributionReportingRequestOptions attributionReporting;
|
||||
[RuntimeEnabled=FetchRetry] RetryOptions retryOptions;
|
||||
// TODO(domfarolino): add support for RequestInit window member.
|
||||
//any window; // can only be set to null
|
||||
};
|
||||
|
39
third_party/blink/renderer/core/fetch/retry_options.idl
vendored
Normal file
39
third_party/blink/renderer/core/fetch/retry_options.idl
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// 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.
|
||||
|
||||
// Explainer: https://github.com/explainers-by-googlers/fetch-retry.
|
||||
// Note: In the final form, we might remove some of these settings if e.g. we
|
||||
// ended up not having use cases for them / browser-controlled policies are
|
||||
// enough. We will re-evaluate them after origin trial.
|
||||
dictionary RetryOptions {
|
||||
// Required: Maximum number of retry attempts after the initial one fails.
|
||||
// A value of 0 means no retries beyond the initial attempt.
|
||||
required unsigned long maxAttempts;
|
||||
|
||||
// Optional: Delay before the first retry attempt in milliseconds.
|
||||
// Defaults to browser-configured value if not specified.
|
||||
unsigned long? initialDelay;
|
||||
|
||||
// Optional: Multiplier for increasing delay between retries (e.g., 2.0 for exponential backoff).
|
||||
// A factor of 1.0 means fixed delay. Defaults to browser-configured value if not specified.
|
||||
double? backoffFactor;
|
||||
|
||||
// Optional: Maximum total time allowed for all retry attempts in milliseconds,
|
||||
// measured from when the first attempt fails. If this duration is exceeded,
|
||||
// no further retries will be made, even if maxAttempts has not been reached.
|
||||
// Defaults to browser-configured value if not specified.
|
||||
unsigned long? maxAge;
|
||||
|
||||
// Optional: Controls whether the browser should continue attempting retries
|
||||
// even after the originating document has been unloaded.
|
||||
// This requires `keepalive: true` to be set on the Request.
|
||||
// Defaults to false.
|
||||
boolean retryAfterUnload = false;
|
||||
|
||||
// Optional: Specifies whether to retry when the HTTP request method is
|
||||
// non-idempotent (e.g. POST, PUT, DELETE). If this is not set while the HTTP
|
||||
// request method of the fetch is non-idempotent, no retry will be attempted.
|
||||
// Defaults to false.
|
||||
boolean retryNonIdempotent = false;
|
||||
};
|
@ -38,6 +38,7 @@
|
||||
#include "net/filter/source_stream_type.h"
|
||||
#include "net/storage_access_api/status.h"
|
||||
#include "services/metrics/public/cpp/ukm_source_id.h"
|
||||
#include "services/network/public/cpp/fetch_retry_options.h"
|
||||
#include "services/network/public/mojom/attribution.mojom-blink.h"
|
||||
#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink-forward.h"
|
||||
#include "services/network/public/mojom/cors.mojom-blink-forward.h"
|
||||
@ -292,6 +293,16 @@ class PLATFORM_EXPORT ResourceRequestHead {
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
bool HasFetchRetryOptions() const { return fetch_retry_options_.has_value(); }
|
||||
const std::optional<network::FetchRetryOptions>& FetchRetryOptions() const {
|
||||
return fetch_retry_options_;
|
||||
}
|
||||
|
||||
void SetFetchRetryOptions(
|
||||
const network::FetchRetryOptions& fetch_retry_options) {
|
||||
fetch_retry_options_ = fetch_retry_options;
|
||||
}
|
||||
|
||||
// True if the request should be considered for computing and attaching the
|
||||
// topics headers.
|
||||
bool GetBrowsingTopics() const { return browsing_topics_; }
|
||||
@ -834,6 +845,8 @@ class PLATFORM_EXPORT ResourceRequestHead {
|
||||
// TODO(crbug.com/382527001): Consider merge this field with `keepalive_`.
|
||||
std::optional<base::UnguessableToken> keepalive_token_;
|
||||
|
||||
std::optional<network::FetchRetryOptions> fetch_retry_options_;
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
bool is_set_url_allowed_ = true;
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink.h"
|
||||
#include "services/network/public/mojom/data_pipe_getter.mojom-blink.h"
|
||||
#include "services/network/public/mojom/data_pipe_getter.mojom.h"
|
||||
#include "services/network/public/mojom/fetch_retry_options.mojom-shared.h"
|
||||
#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
|
||||
#include "services/network/public/mojom/trust_tokens.mojom.h"
|
||||
#include "third_party/blink/public/common/loader/network_utils.h"
|
||||
@ -362,6 +363,9 @@ void PopulateResourceRequest(const ResourceRequestHead& src,
|
||||
dest->throttling_profile_id = src.GetDevToolsToken();
|
||||
dest->trust_token_params = ConvertTrustTokenParams(src.TrustTokenParams());
|
||||
dest->required_ip_address_space = src.GetTargetAddressSpace();
|
||||
if (src.HasFetchRetryOptions()) {
|
||||
dest->fetch_retry_options = src.FetchRetryOptions();
|
||||
}
|
||||
|
||||
if (base::UnguessableToken window_id = src.GetFetchWindowId())
|
||||
dest->fetch_window_id = std::make_optional(window_id);
|
||||
|
@ -2065,6 +2065,10 @@
|
||||
name: "FetchLaterAPI",
|
||||
status: "stable",
|
||||
},
|
||||
{
|
||||
name: "FetchRetry",
|
||||
status: "experimental",
|
||||
},
|
||||
{
|
||||
name: "FetchUploadStreaming",
|
||||
status: "stable",
|
||||
|
Reference in New Issue
Block a user