forked from mirrors/gecko-dev
Bug 1839319 - Add fetchpriority support for fetch() API. r=valentin,necko-reviewers,webidl,saschanaz,fredw
This is to add basic fetch priority support. It introduces preference of fetch priority adjustment as per to recent discussions. We need to refine the fetchpriority mapping taking into account of destination, which will be addressed in Bug 1881040. In addition, this changes the relervant prefs type to atomic type to accommodate the access of the prefs off the main thread in the worker case. Differential Revision: https://phabricator.services.mozilla.com/D200778
This commit is contained in:
parent
31f84e20ac
commit
aa6bf5aefc
10 changed files with 62 additions and 21 deletions
|
|
@ -9,6 +9,7 @@
|
||||||
#include "mozilla/TaskQueue.h"
|
#include "mozilla/TaskQueue.h"
|
||||||
#include "mozilla/dom/FetchDriver.h"
|
#include "mozilla/dom/FetchDriver.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/FetchPriority.h"
|
||||||
#include "mozilla/dom/ReferrerInfo.h"
|
#include "mozilla/dom/ReferrerInfo.h"
|
||||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
|
|
@ -840,11 +841,20 @@ nsresult FetchDriver::HttpFetch(
|
||||||
nsIClassOfService::Tail);
|
nsIClassOfService::Tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsTrackingFetch &&
|
if (nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(chan)) {
|
||||||
StaticPrefs::privacy_trackingprotection_lower_network_priority()) {
|
if (mIsTrackingFetch &&
|
||||||
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(chan);
|
StaticPrefs::privacy_trackingprotection_lower_network_priority()) {
|
||||||
if (p) {
|
|
||||||
p->SetPriority(nsISupportsPriority::PRIORITY_LOWEST);
|
p->SetPriority(nsISupportsPriority::PRIORITY_LOWEST);
|
||||||
|
} else if (StaticPrefs::network_fetchpriority_enabled()) {
|
||||||
|
// TODO: Bug 1881040 - we need to take into account of destination for the
|
||||||
|
// fetchpriority mapping.
|
||||||
|
const auto fetchPriority = ToFetchPriority(mRequest->GetPriorityMode());
|
||||||
|
// The spec defines the priority to be set in an implementation defined
|
||||||
|
// manner (<https://fetch.spec.whatwg.org/#concept-fetch>, step 15.
|
||||||
|
// See corresponding preferences in StaticPrefList.yaml for more context.
|
||||||
|
const int32_t supportsPriorityDelta =
|
||||||
|
FETCH_PRIORITY_ADJUSTMENT_FOR(global_fetch_api, fetchPriority);
|
||||||
|
p->AdjustPriority(supportsPriorityDelta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ SafeRefPtr<InternalRequest> InternalRequest::GetRequestConstructorCopy(
|
||||||
copy->mCredentialsMode = mCredentialsMode;
|
copy->mCredentialsMode = mCredentialsMode;
|
||||||
copy->mCacheMode = mCacheMode;
|
copy->mCacheMode = mCacheMode;
|
||||||
copy->mRedirectMode = mRedirectMode;
|
copy->mRedirectMode = mRedirectMode;
|
||||||
|
copy->mPriorityMode = mPriorityMode;
|
||||||
copy->mContentPolicyTypeOverridden = mContentPolicyTypeOverridden;
|
copy->mContentPolicyTypeOverridden = mContentPolicyTypeOverridden;
|
||||||
|
|
||||||
copy->mPreferredAlternativeDataType = mPreferredAlternativeDataType;
|
copy->mPreferredAlternativeDataType = mPreferredAlternativeDataType;
|
||||||
|
|
@ -91,7 +92,8 @@ InternalRequest::InternalRequest(const nsACString& aURL,
|
||||||
mMode(RequestMode::No_cors),
|
mMode(RequestMode::No_cors),
|
||||||
mCredentialsMode(RequestCredentials::Omit),
|
mCredentialsMode(RequestCredentials::Omit),
|
||||||
mCacheMode(RequestCache::Default),
|
mCacheMode(RequestCache::Default),
|
||||||
mRedirectMode(RequestRedirect::Follow) {
|
mRedirectMode(RequestRedirect::Follow),
|
||||||
|
mPriorityMode(RequestPriority::Auto) {
|
||||||
MOZ_ASSERT(!aURL.IsEmpty());
|
MOZ_ASSERT(!aURL.IsEmpty());
|
||||||
AddURL(aURL, aFragment);
|
AddURL(aURL, aFragment);
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +103,8 @@ InternalRequest::InternalRequest(
|
||||||
RequestCache aCacheMode, RequestMode aMode,
|
RequestCache aCacheMode, RequestMode aMode,
|
||||||
RequestRedirect aRequestRedirect, RequestCredentials aRequestCredentials,
|
RequestRedirect aRequestRedirect, RequestCredentials aRequestCredentials,
|
||||||
const nsAString& aReferrer, ReferrerPolicy aReferrerPolicy,
|
const nsAString& aReferrer, ReferrerPolicy aReferrerPolicy,
|
||||||
nsContentPolicyType aContentPolicyType, const nsAString& aIntegrity)
|
RequestPriority aPriority, nsContentPolicyType aContentPolicyType,
|
||||||
|
const nsAString& aIntegrity)
|
||||||
: mMethod(aMethod),
|
: mMethod(aMethod),
|
||||||
mHeaders(aHeaders),
|
mHeaders(aHeaders),
|
||||||
mBodyLength(InternalResponse::UNKNOWN_BODY_SIZE),
|
mBodyLength(InternalResponse::UNKNOWN_BODY_SIZE),
|
||||||
|
|
@ -113,6 +116,7 @@ InternalRequest::InternalRequest(
|
||||||
mCredentialsMode(aRequestCredentials),
|
mCredentialsMode(aRequestCredentials),
|
||||||
mCacheMode(aCacheMode),
|
mCacheMode(aCacheMode),
|
||||||
mRedirectMode(aRequestRedirect),
|
mRedirectMode(aRequestRedirect),
|
||||||
|
mPriorityMode(aPriority),
|
||||||
mIntegrity(aIntegrity) {
|
mIntegrity(aIntegrity) {
|
||||||
MOZ_ASSERT(!aURL.IsEmpty());
|
MOZ_ASSERT(!aURL.IsEmpty());
|
||||||
AddURL(aURL, aFragment);
|
AddURL(aURL, aFragment);
|
||||||
|
|
@ -132,6 +136,7 @@ InternalRequest::InternalRequest(const InternalRequest& aOther,
|
||||||
mResponseTainting(aOther.mResponseTainting),
|
mResponseTainting(aOther.mResponseTainting),
|
||||||
mCacheMode(aOther.mCacheMode),
|
mCacheMode(aOther.mCacheMode),
|
||||||
mRedirectMode(aOther.mRedirectMode),
|
mRedirectMode(aOther.mRedirectMode),
|
||||||
|
mPriorityMode(aOther.mPriorityMode),
|
||||||
mIntegrity(aOther.mIntegrity),
|
mIntegrity(aOther.mIntegrity),
|
||||||
mMozErrors(aOther.mMozErrors),
|
mMozErrors(aOther.mMozErrors),
|
||||||
mFragment(aOther.mFragment),
|
mFragment(aOther.mFragment),
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@ class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
|
||||||
RequestRedirect aRequestRedirect,
|
RequestRedirect aRequestRedirect,
|
||||||
RequestCredentials aRequestCredentials,
|
RequestCredentials aRequestCredentials,
|
||||||
const nsAString& aReferrer, ReferrerPolicy aReferrerPolicy,
|
const nsAString& aReferrer, ReferrerPolicy aReferrerPolicy,
|
||||||
|
RequestPriority aPriority,
|
||||||
nsContentPolicyType aContentPolicyType,
|
nsContentPolicyType aContentPolicyType,
|
||||||
const nsAString& aIntegrity);
|
const nsAString& aIntegrity);
|
||||||
|
|
||||||
|
|
@ -250,6 +251,12 @@ class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
|
||||||
mRedirectMode = aRedirectMode;
|
mRedirectMode = aRedirectMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RequestPriority GetPriorityMode() const { return mPriorityMode; }
|
||||||
|
|
||||||
|
void SetPriorityMode(RequestPriority aPriorityMode) {
|
||||||
|
mPriorityMode = aPriorityMode;
|
||||||
|
}
|
||||||
|
|
||||||
const nsString& GetIntegrity() const { return mIntegrity; }
|
const nsString& GetIntegrity() const { return mIntegrity; }
|
||||||
|
|
||||||
void SetIntegrity(const nsAString& aIntegrity) {
|
void SetIntegrity(const nsAString& aIntegrity) {
|
||||||
|
|
@ -445,6 +452,7 @@ class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
|
||||||
LoadTainting mResponseTainting = LoadTainting::Basic;
|
LoadTainting mResponseTainting = LoadTainting::Basic;
|
||||||
RequestCache mCacheMode;
|
RequestCache mCacheMode;
|
||||||
RequestRedirect mRedirectMode;
|
RequestRedirect mRedirectMode;
|
||||||
|
RequestPriority mPriorityMode = RequestPriority::Auto;
|
||||||
nsString mIntegrity;
|
nsString mIntegrity;
|
||||||
bool mMozErrors = false;
|
bool mMozErrors = false;
|
||||||
nsCString mFragment;
|
nsCString mFragment;
|
||||||
|
|
|
||||||
|
|
@ -430,6 +430,13 @@ SafeRefPtr<Request> Request::Constructor(nsIGlobalObject* aGlobal,
|
||||||
signal = aInit.mSignal.Value();
|
signal = aInit.mSignal.Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://fetch.spec.whatwg.org/#dom-global-fetch
|
||||||
|
// https://fetch.spec.whatwg.org/#dom-request
|
||||||
|
// The priority of init overrides input's priority.
|
||||||
|
if (aInit.mPriority.WasPassed()) {
|
||||||
|
request->SetPriorityMode(aInit.mPriority.Value());
|
||||||
|
}
|
||||||
|
|
||||||
UniquePtr<mozilla::ipc::PrincipalInfo> principalInfo;
|
UniquePtr<mozilla::ipc::PrincipalInfo> principalInfo;
|
||||||
nsILoadInfo::CrossOriginEmbedderPolicy coep =
|
nsILoadInfo::CrossOriginEmbedderPolicy coep =
|
||||||
nsILoadInfo::EMBEDDER_POLICY_NULL;
|
nsILoadInfo::EMBEDDER_POLICY_NULL;
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@ class Request final : public FetchBody<Request>, public nsWrapperCache {
|
||||||
|
|
||||||
RequestRedirect Redirect() const { return mRequest->GetRedirectMode(); }
|
RequestRedirect Redirect() const { return mRequest->GetRedirectMode(); }
|
||||||
|
|
||||||
|
RequestPriority Priority() const { return mRequest->GetPriorityMode(); }
|
||||||
|
|
||||||
void GetIntegrity(nsAString& aIntegrity) const {
|
void GetIntegrity(nsAString& aIntegrity) const {
|
||||||
aIntegrity = mRequest->GetIntegrity();
|
aIntegrity = mRequest->GetIntegrity();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,9 @@ dictionary RequestInit {
|
||||||
|
|
||||||
AbortSignal? signal;
|
AbortSignal? signal;
|
||||||
|
|
||||||
|
[Pref="network.fetchpriority.enabled"]
|
||||||
|
RequestPriority priority;
|
||||||
|
|
||||||
[Pref="dom.fetchObserver.enabled"]
|
[Pref="dom.fetchObserver.enabled"]
|
||||||
ObserverCallback observe;
|
ObserverCallback observe;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11778,7 +11778,7 @@
|
||||||
# Indicates whether the `fetchpriority` attribute for elements which support it
|
# Indicates whether the `fetchpriority` attribute for elements which support it
|
||||||
# (e.g. `<script>`) is enabled.
|
# (e.g. `<script>`) is enabled.
|
||||||
- name: network.fetchpriority.enabled
|
- name: network.fetchpriority.enabled
|
||||||
type: bool
|
type: RelaxedAtomicBool
|
||||||
value: false
|
value: false
|
||||||
mirror: always
|
mirror: always
|
||||||
|
|
||||||
|
|
@ -11962,6 +11962,24 @@
|
||||||
value: 0
|
value: 0
|
||||||
mirror: always
|
mirror: always
|
||||||
|
|
||||||
|
# Adjustments to apply to the internal priority of gloable fetch API
|
||||||
|
# for fetchpriority=low/high/auto with respect to the case when
|
||||||
|
# network.fetchpriority is disabled.
|
||||||
|
# - When the flag is disabled, Gecko currently sets priority to NORMAL.
|
||||||
|
# - When the flag is enabled, it respectively maps to LOW/HIGH/NORMAL.
|
||||||
|
- name: network.fetchpriority.adjustments.global-fetch-api.low
|
||||||
|
type: RelaxedAtomicInt32
|
||||||
|
value: 10
|
||||||
|
mirror: always
|
||||||
|
- name: network.fetchpriority.adjustments.global-fetch-api.high
|
||||||
|
type: RelaxedAtomicInt32
|
||||||
|
value: -10
|
||||||
|
mirror: always
|
||||||
|
- name: network.fetchpriority.adjustments.global-fetch-api.auto
|
||||||
|
type: RelaxedAtomicInt32
|
||||||
|
value: 0
|
||||||
|
mirror: always
|
||||||
|
|
||||||
# Enables `<link rel="preconnect">` tag and `Link: rel=preconnect` response header
|
# Enables `<link rel="preconnect">` tag and `Link: rel=preconnect` response header
|
||||||
# handling.
|
# handling.
|
||||||
- name: network.preconnect
|
- name: network.preconnect
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,4 @@
|
||||||
|
prefs: [network.fetchpriority.enabled:true]
|
||||||
[request-init-priority.any.html]
|
[request-init-priority.any.html]
|
||||||
[new Request() throws a TypeError if any of RequestInit's members' values are invalid]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[fetch() with an invalid priority returns a rejected promise with a TypeError]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
|
|
||||||
[request-init-priority.any.worker.html]
|
[request-init-priority.any.worker.html]
|
||||||
[new Request() throws a TypeError if any of RequestInit's members' values are invalid]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[fetch() with an invalid priority returns a rejected promise with a TypeError]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,5 @@
|
||||||
[image-dynamic-load.h2.html: test different 'fetchpriority' values]
|
[image-dynamic-load.h2.html: test different 'fetchpriority' values]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[fetch-init.h2.html: test different 'fetchpriority' values]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[image-initial-load.h2.html: test different 'fetchpriority' values]
|
[image-initial-load.h2.html: test different 'fetchpriority' values]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
"deferred-style": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL,
|
"deferred-style": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL,
|
||||||
"link-preload-style": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGHEST,
|
"link-preload-style": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGHEST,
|
||||||
"non-deferred-style": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL,
|
"non-deferred-style": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL,
|
||||||
|
"global-fetch-api": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL,
|
||||||
};
|
};
|
||||||
for (const name in prioritiesWhenFetchpriorityDisabled) {
|
for (const name in prioritiesWhenFetchpriorityDisabled) {
|
||||||
let adjustments = {};
|
let adjustments = {};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue