Backed out 5 changesets (bug 1761242, bug 1744822, bug 1761252) for causing browser-chrome failures in netwerk/test/browser/browser_103_assets.js CLOSED TREE
Backed out changeset 33cc08eb51b3 (bug 1744822) Backed out changeset b70697d24e75 (bug 1761252) Backed out changeset 4a5e10110c6a (bug 1761242) Backed out changeset 7cda175b833d (bug 1761242) Backed out changeset 4f5ed111093b (bug 1761242)
This commit is contained in:
@@ -23,7 +23,6 @@
|
|||||||
#include "js/loader/ModuleLoadRequest.h"
|
#include "js/loader/ModuleLoadRequest.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
#include "nsContentSecurityManager.h"
|
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
#include "mozilla/dom/AutoEntryScript.h"
|
#include "mozilla/dom/AutoEntryScript.h"
|
||||||
@@ -89,20 +88,24 @@ bool ModuleLoader::CanStartLoad(ModuleLoadRequest* aRequest, nsresult* aRvOut) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult ModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
|
nsresult ModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
|
||||||
|
nsSecurityFlags securityFlags;
|
||||||
|
|
||||||
// According to the spec, module scripts have different behaviour to classic
|
// According to the spec, module scripts have different behaviour to classic
|
||||||
// scripts and always use CORS. Only exception: Non linkable about: pages
|
// scripts and always use CORS. Only exception: Non linkable about: pages
|
||||||
// which load local module scripts.
|
// which load local module scripts.
|
||||||
bool isAboutPageLoadingChromeURI = ScriptLoader::IsAboutPageLoadingChromeURI(
|
if (GetScriptLoader()->IsAboutPageLoadingChromeURI(
|
||||||
aRequest, GetScriptLoader()->GetDocument());
|
aRequest, GetScriptLoader()->GetDocument())) {
|
||||||
|
securityFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL;
|
||||||
nsContentSecurityManager::CORSSecurityMapping corsMapping =
|
} else {
|
||||||
isAboutPageLoadingChromeURI
|
securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT;
|
||||||
? nsContentSecurityManager::CORSSecurityMapping::DISABLE_CORS_CHECKS
|
if (aRequest->CORSMode() == CORS_NONE ||
|
||||||
: nsContentSecurityManager::CORSSecurityMapping::REQUIRE_CORS_CHECKS;
|
aRequest->CORSMode() == CORS_ANONYMOUS) {
|
||||||
|
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||||
nsSecurityFlags securityFlags =
|
} else {
|
||||||
nsContentSecurityManager::ComputeSecurityFlags(aRequest->CORSMode(),
|
MOZ_ASSERT(aRequest->CORSMode() == CORS_USE_CREDENTIALS);
|
||||||
corsMapping);
|
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
#include "js/Utility.h"
|
#include "js/Utility.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
#include "nsContentSecurityManager.h"
|
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
@@ -557,9 +556,14 @@ nsresult ScriptLoader::StartClassicLoad(ScriptLoadRequest* aRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsSecurityFlags securityFlags =
|
nsSecurityFlags securityFlags =
|
||||||
nsContentSecurityManager::ComputeSecurityFlags(
|
aRequest->CORSMode() == CORS_NONE
|
||||||
aRequest->CORSMode(), nsContentSecurityManager::CORSSecurityMapping::
|
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
|
||||||
CORS_NONE_MAPS_TO_DISABLED_CORS_CHECKS);
|
: nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT;
|
||||||
|
if (aRequest->CORSMode() == CORS_ANONYMOUS) {
|
||||||
|
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||||
|
} else if (aRequest->CORSMode() == CORS_USE_CREDENTIALS) {
|
||||||
|
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
||||||
|
|
||||||
|
|||||||
@@ -992,44 +992,6 @@ void nsContentSecurityManager::MeasureUnexpectedPrivilegedLoads(
|
|||||||
extra);
|
extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
|
||||||
nsSecurityFlags nsContentSecurityManager::ComputeSecurityFlags(
|
|
||||||
mozilla::CORSMode aCORSMode, CORSSecurityMapping aCORSSecurityMapping) {
|
|
||||||
if (aCORSSecurityMapping == CORSSecurityMapping::DISABLE_CORS_CHECKS) {
|
|
||||||
return nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (aCORSMode) {
|
|
||||||
case CORS_NONE:
|
|
||||||
if (aCORSSecurityMapping == CORSSecurityMapping::REQUIRE_CORS_CHECKS) {
|
|
||||||
// CORS_NONE gets treated like CORS_ANONYMOUS in this mode
|
|
||||||
return nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT |
|
|
||||||
nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
|
||||||
} else if (aCORSSecurityMapping ==
|
|
||||||
CORSSecurityMapping::CORS_NONE_MAPS_TO_INHERITED_CONTEXT) {
|
|
||||||
// CORS_NONE inherits
|
|
||||||
return nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT;
|
|
||||||
} else {
|
|
||||||
// CORS_NONE_MAPS_TO_DISABLED_CORS_CHECKS, the only remaining enum
|
|
||||||
// variant. CORSSecurityMapping::DISABLE_CORS_CHECKS returned early.
|
|
||||||
MOZ_ASSERT(aCORSSecurityMapping ==
|
|
||||||
CORSSecurityMapping::CORS_NONE_MAPS_TO_DISABLED_CORS_CHECKS);
|
|
||||||
return nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL;
|
|
||||||
}
|
|
||||||
case CORS_ANONYMOUS:
|
|
||||||
return nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT |
|
|
||||||
nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
|
||||||
case CORS_USE_CREDENTIALS:
|
|
||||||
return nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT |
|
|
||||||
nsILoadInfo::SEC_COOKIES_INCLUDE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_ASSERT_UNREACHABLE("Invalid aCORSMode enum value");
|
|
||||||
return nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT |
|
|
||||||
nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
nsresult nsContentSecurityManager::CheckAllowLoadInSystemPrivilegedContext(
|
nsresult nsContentSecurityManager::CheckAllowLoadInSystemPrivilegedContext(
|
||||||
nsIChannel* aChannel) {
|
nsIChannel* aChannel) {
|
||||||
|
|||||||
@@ -7,11 +7,9 @@
|
|||||||
#ifndef nsContentSecurityManager_h___
|
#ifndef nsContentSecurityManager_h___
|
||||||
#define nsContentSecurityManager_h___
|
#define nsContentSecurityManager_h___
|
||||||
|
|
||||||
#include "mozilla/CORSMode.h"
|
|
||||||
#include "nsIContentSecurityManager.h"
|
#include "nsIContentSecurityManager.h"
|
||||||
#include "nsIChannel.h"
|
#include "nsIChannel.h"
|
||||||
#include "nsIChannelEventSink.h"
|
#include "nsIChannelEventSink.h"
|
||||||
#include "nsILoadInfo.h"
|
|
||||||
|
|
||||||
class nsILoadInfo;
|
class nsILoadInfo;
|
||||||
class nsIStreamListener;
|
class nsIStreamListener;
|
||||||
@@ -44,33 +42,6 @@ class nsContentSecurityManager : public nsIContentSecurityManager,
|
|||||||
nsIURI* aFinalURI,
|
nsIURI* aFinalURI,
|
||||||
const nsACString& aRemoteType);
|
const nsACString& aRemoteType);
|
||||||
|
|
||||||
enum CORSSecurityMapping {
|
|
||||||
// Disables all CORS checking overriding the value of aCORSMode. All checks
|
|
||||||
// are disabled even when CORSMode::CORS_ANONYMOUS or
|
|
||||||
// CORSMode::CORS_USE_CREDENTIALS is passed. This is mostly used for chrome
|
|
||||||
// code, where we don't need security checks. See
|
|
||||||
// SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL for the detailed explanation
|
|
||||||
// of the security mode.
|
|
||||||
DISABLE_CORS_CHECKS,
|
|
||||||
// Disables all CORS checking on CORSMode::CORS_NONE. The other two CORS
|
|
||||||
// modes CORSMode::CORS_ANONYMOUS and CORSMode::CORS_USE_CREDENTIALS are
|
|
||||||
// respected.
|
|
||||||
CORS_NONE_MAPS_TO_DISABLED_CORS_CHECKS,
|
|
||||||
// Allow load from any origin, but cross-origin requests require CORS. See
|
|
||||||
// SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT. Like above the other two
|
|
||||||
// CORS modes are unaffected and get parsed.
|
|
||||||
CORS_NONE_MAPS_TO_INHERITED_CONTEXT,
|
|
||||||
// Always require the server to acknowledge the request via CORS.
|
|
||||||
// CORSMode::CORS_NONE is parsed as if CORSMode::CORS_ANONYMOUS is passed.
|
|
||||||
REQUIRE_CORS_CHECKS,
|
|
||||||
};
|
|
||||||
|
|
||||||
// computes the security flags for the requested CORS mode
|
|
||||||
// @param aCORSSecurityMapping: See CORSSecurityMapping for variant
|
|
||||||
// descriptions
|
|
||||||
static nsSecurityFlags ComputeSecurityFlags(
|
|
||||||
mozilla::CORSMode aCORSMode, CORSSecurityMapping aCORSSecurityMapping);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static nsresult CheckChannel(nsIChannel* aChannel);
|
static nsresult CheckChannel(nsIChannel* aChannel);
|
||||||
static nsresult CheckFTPSubresourceLoad(nsIChannel* aChannel);
|
static nsresult CheckFTPSubresourceLoad(nsIChannel* aChannel);
|
||||||
|
|||||||
@@ -37,7 +37,6 @@
|
|||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsContentPolicyUtils.h"
|
#include "nsContentPolicyUtils.h"
|
||||||
#include "nsContentSecurityManager.h"
|
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsHttpChannel.h"
|
#include "nsHttpChannel.h"
|
||||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||||
@@ -861,10 +860,14 @@ static nsresult NewImageChannel(
|
|||||||
//
|
//
|
||||||
|
|
||||||
nsSecurityFlags securityFlags =
|
nsSecurityFlags securityFlags =
|
||||||
nsContentSecurityManager::ComputeSecurityFlags(
|
aCORSMode == CORS_NONE
|
||||||
aCORSMode, nsContentSecurityManager::CORSSecurityMapping::
|
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT
|
||||||
CORS_NONE_MAPS_TO_INHERITED_CONTEXT);
|
: nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT;
|
||||||
|
if (aCORSMode == CORS_ANONYMOUS) {
|
||||||
|
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||||
|
} else if (aCORSMode == CORS_USE_CREDENTIALS) {
|
||||||
|
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||||
|
}
|
||||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
||||||
|
|
||||||
// Note we are calling NS_NewChannelWithTriggeringPrincipal() here with a
|
// Note we are calling NS_NewChannelWithTriggeringPrincipal() here with a
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include "gfxUserFontSet.h"
|
#include "gfxUserFontSet.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "nsContentSecurityManager.h"
|
|
||||||
#include "nsIClassOfService.h"
|
#include "nsIClassOfService.h"
|
||||||
#include "nsIHttpChannel.h"
|
#include "nsIHttpChannel.h"
|
||||||
#include "nsISupportsPriority.h"
|
#include "nsISupportsPriority.h"
|
||||||
@@ -54,15 +53,13 @@ nsresult FontPreloader::BuildChannel(
|
|||||||
|
|
||||||
// aCORSMode is ignored. We always load as crossorigin=anonymous, but a
|
// aCORSMode is ignored. We always load as crossorigin=anonymous, but a
|
||||||
// preload started with anything other then "anonymous" will never be found.
|
// preload started with anything other then "anonymous" will never be found.
|
||||||
nsContentSecurityManager::CORSSecurityMapping corsMapping =
|
|
||||||
aURI->SchemeIs("file")
|
|
||||||
? nsContentSecurityManager::CORSSecurityMapping::
|
|
||||||
CORS_NONE_MAPS_TO_INHERITED_CONTEXT
|
|
||||||
: nsContentSecurityManager::CORSSecurityMapping::REQUIRE_CORS_CHECKS;
|
|
||||||
|
|
||||||
nsSecurityFlags securityFlags =
|
uint32_t securityFlags = 0;
|
||||||
nsContentSecurityManager::ComputeSecurityFlags(CORSMode::CORS_NONE,
|
if (aURI->SchemeIs("file")) {
|
||||||
corsMapping);
|
securityFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT;
|
||||||
|
} else {
|
||||||
|
securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
nsContentPolicyType contentPolicyType =
|
nsContentPolicyType contentPolicyType =
|
||||||
aIsPreload ? nsIContentPolicy::TYPE_INTERNAL_FONT_PRELOAD
|
aIsPreload ? nsIContentPolicy::TYPE_INTERNAL_FONT_PRELOAD
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include "nsITimedChannel.h"
|
#include "nsITimedChannel.h"
|
||||||
#include "nsICachingChannel.h"
|
#include "nsICachingChannel.h"
|
||||||
#include "nsSyncLoadService.h"
|
#include "nsSyncLoadService.h"
|
||||||
#include "nsContentSecurityManager.h"
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
@@ -1231,14 +1230,9 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState,
|
|||||||
mDocument);
|
mDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronous loads should only be used internally. Therefore no CORS
|
|
||||||
// policy is needed.
|
|
||||||
nsSecurityFlags securityFlags =
|
nsSecurityFlags securityFlags =
|
||||||
nsContentSecurityManager::ComputeSecurityFlags(
|
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT |
|
||||||
CORSMode::CORS_NONE, nsContentSecurityManager::CORSSecurityMapping::
|
nsILoadInfo::SEC_ALLOW_CHROME;
|
||||||
CORS_NONE_MAPS_TO_INHERITED_CONTEXT);
|
|
||||||
|
|
||||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
|
||||||
|
|
||||||
nsContentPolicyType contentPolicyType =
|
nsContentPolicyType contentPolicyType =
|
||||||
aLoadData.mPreloadKind == StylePreloadKind::None
|
aLoadData.mPreloadKind == StylePreloadKind::None
|
||||||
@@ -1382,12 +1376,16 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState,
|
|||||||
mSyncCallback = true;
|
mSyncCallback = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CORSMode ourCORSMode = aLoadData.mSheet->GetCORSMode();
|
||||||
nsSecurityFlags securityFlags =
|
nsSecurityFlags securityFlags =
|
||||||
nsContentSecurityManager::ComputeSecurityFlags(
|
ourCORSMode == CORS_NONE
|
||||||
aLoadData.mSheet->GetCORSMode(),
|
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT
|
||||||
nsContentSecurityManager::CORSSecurityMapping::
|
: nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT;
|
||||||
CORS_NONE_MAPS_TO_INHERITED_CONTEXT);
|
if (ourCORSMode == CORS_ANONYMOUS) {
|
||||||
|
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||||
|
} else if (ourCORSMode == CORS_USE_CREDENTIALS) {
|
||||||
|
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||||
|
}
|
||||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
||||||
|
|
||||||
nsContentPolicyType contentPolicyType =
|
nsContentPolicyType contentPolicyType =
|
||||||
|
|||||||
@@ -3403,21 +3403,6 @@ void LinkHeader::Reset() {
|
|||||||
mCrossOrigin.SetIsVoid(true);
|
mCrossOrigin.SetIsVoid(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult LinkHeader::NewResolveHref(nsIURI** aOutURI, nsIURI* aBaseURI) const {
|
|
||||||
if (mAnchor.IsEmpty()) {
|
|
||||||
// use the base uri
|
|
||||||
return NS_NewURI(aOutURI, mHref, nullptr, aBaseURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute the anchored URI
|
|
||||||
nsCOMPtr<nsIURI> anchoredURI;
|
|
||||||
nsresult rv =
|
|
||||||
NS_NewURI(getter_AddRefs(anchoredURI), mAnchor, nullptr, aBaseURI);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_NewURI(aOutURI, mHref, nullptr, anchoredURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LinkHeader::operator==(const LinkHeader& rhs) const {
|
bool LinkHeader::operator==(const LinkHeader& rhs) const {
|
||||||
return mHref == rhs.mHref && mRel == rhs.mRel && mTitle == rhs.mTitle &&
|
return mHref == rhs.mHref && mRel == rhs.mRel && mTitle == rhs.mTitle &&
|
||||||
mIntegrity == rhs.mIntegrity && mSrcset == rhs.mSrcset &&
|
mIntegrity == rhs.mIntegrity && mSrcset == rhs.mSrcset &&
|
||||||
|
|||||||
@@ -1012,9 +1012,6 @@ struct LinkHeader {
|
|||||||
|
|
||||||
LinkHeader();
|
LinkHeader();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
nsresult NewResolveHref(nsIURI** aOutURI, nsIURI* aBaseURI) const;
|
|
||||||
|
|
||||||
bool operator==(const LinkHeader& rhs) const;
|
bool operator==(const LinkHeader& rhs) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,10 @@
|
|||||||
#include "EarlyHintsService.h"
|
#include "EarlyHintsService.h"
|
||||||
#include "ErrorList.h"
|
#include "ErrorList.h"
|
||||||
#include "mozilla/CORSMode.h"
|
#include "mozilla/CORSMode.h"
|
||||||
#include "mozilla/dom/Element.h"
|
|
||||||
#include "mozilla/dom/ReferrerInfo.h"
|
#include "mozilla/dom/ReferrerInfo.h"
|
||||||
#include "mozilla/Logging.h"
|
#include "mozilla/Logging.h"
|
||||||
#include "nsAttrValue.h"
|
#include "nsAttrValue.h"
|
||||||
#include "nsAttrValueInlines.h"
|
#include "nsAttrValueInlines.h"
|
||||||
#include "nsContentSecurityManager.h"
|
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||||
@@ -20,9 +18,9 @@
|
|||||||
#include "nsIChannel.h"
|
#include "nsIChannel.h"
|
||||||
#include "nsIHttpChannel.h"
|
#include "nsIHttpChannel.h"
|
||||||
#include "nsIInputStream.h"
|
#include "nsIInputStream.h"
|
||||||
#include "nsILoadInfo.h"
|
|
||||||
#include "nsIReferrerInfo.h"
|
#include "nsIReferrerInfo.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
|
#include "nsNetUtil.h"
|
||||||
#include "nsStreamUtils.h"
|
#include "nsStreamUtils.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -71,78 +69,14 @@ EarlyHintPreloader::EarlyHintPreloader(nsIURI* aURI) : mURI(aURI) {}
|
|||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
Maybe<PreloadHashKey> EarlyHintPreloader::GenerateHashKey(
|
Maybe<PreloadHashKey> EarlyHintPreloader::GenerateHashKey(
|
||||||
ASDestination aAs, nsIURI* aURI, nsIPrincipal* aPrincipal,
|
ASDestination aAs, nsIURI* aURI, nsIPrincipal* aPrincipal) {
|
||||||
CORSMode aCorsMode, const nsAString& aType) {
|
|
||||||
if (aAs == ASDestination::DESTINATION_FONT) {
|
|
||||||
return Some(PreloadHashKey::CreateAsFont(aURI, aCorsMode));
|
|
||||||
}
|
|
||||||
if (aAs == ASDestination::DESTINATION_IMAGE) {
|
if (aAs == ASDestination::DESTINATION_IMAGE) {
|
||||||
return Some(PreloadHashKey::CreateAsImage(aURI, aPrincipal, aCorsMode));
|
return Some(
|
||||||
}
|
PreloadHashKey::CreateAsImage(aURI, aPrincipal, CORSMode::CORS_NONE));
|
||||||
if (aAs == ASDestination::DESTINATION_SCRIPT) {
|
|
||||||
JS::loader::ScriptKind scriptKind = JS::loader::ScriptKind::eClassic;
|
|
||||||
if (aType.LowerCaseEqualsASCII("module")) {
|
|
||||||
scriptKind = JS::loader::ScriptKind::eModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Some(PreloadHashKey::CreateAsScript(aURI, aCorsMode, scriptKind));
|
|
||||||
}
|
|
||||||
if (aAs == ASDestination::DESTINATION_STYLE) {
|
|
||||||
return Some(PreloadHashKey::CreateAsStyle(
|
|
||||||
aURI, aPrincipal, aCorsMode,
|
|
||||||
css::SheetParsingMode::eAuthorSheetFeatures));
|
|
||||||
}
|
|
||||||
if (aAs == ASDestination::DESTINATION_FETCH) {
|
|
||||||
return Some(PreloadHashKey::CreateAsFetch(aURI, aCorsMode));
|
|
||||||
}
|
}
|
||||||
return Nothing();
|
return Nothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
|
||||||
nsSecurityFlags EarlyHintPreloader::ComputeSecurityFlags(CORSMode aCORSMode,
|
|
||||||
ASDestination aAs,
|
|
||||||
bool aIsModule) {
|
|
||||||
if (aAs == ASDestination::DESTINATION_FONT) {
|
|
||||||
return nsContentSecurityManager::ComputeSecurityFlags(
|
|
||||||
CORSMode::CORS_NONE,
|
|
||||||
nsContentSecurityManager::CORSSecurityMapping::REQUIRE_CORS_CHECKS);
|
|
||||||
}
|
|
||||||
if (aAs == ASDestination::DESTINATION_IMAGE) {
|
|
||||||
return nsContentSecurityManager::ComputeSecurityFlags(
|
|
||||||
aCORSMode, nsContentSecurityManager::CORSSecurityMapping::
|
|
||||||
CORS_NONE_MAPS_TO_INHERITED_CONTEXT) |
|
|
||||||
nsILoadInfo::SEC_ALLOW_CHROME;
|
|
||||||
}
|
|
||||||
if (aAs == ASDestination::DESTINATION_SCRIPT) {
|
|
||||||
if (aIsModule) {
|
|
||||||
return nsContentSecurityManager::ComputeSecurityFlags(
|
|
||||||
aCORSMode, nsContentSecurityManager::CORSSecurityMapping::
|
|
||||||
REQUIRE_CORS_CHECKS) |
|
|
||||||
nsILoadInfo::SEC_ALLOW_CHROME;
|
|
||||||
}
|
|
||||||
return nsContentSecurityManager::ComputeSecurityFlags(
|
|
||||||
aCORSMode, nsContentSecurityManager::CORSSecurityMapping::
|
|
||||||
CORS_NONE_MAPS_TO_DISABLED_CORS_CHECKS) |
|
|
||||||
nsILoadInfo::SEC_ALLOW_CHROME;
|
|
||||||
}
|
|
||||||
if (aAs == ASDestination::DESTINATION_STYLE) {
|
|
||||||
return nsContentSecurityManager::ComputeSecurityFlags(
|
|
||||||
aCORSMode, nsContentSecurityManager::CORSSecurityMapping::
|
|
||||||
CORS_NONE_MAPS_TO_INHERITED_CONTEXT) |
|
|
||||||
nsILoadInfo::SEC_ALLOW_CHROME;
|
|
||||||
;
|
|
||||||
}
|
|
||||||
if (aAs == ASDestination::DESTINATION_FETCH) {
|
|
||||||
return nsContentSecurityManager::ComputeSecurityFlags(
|
|
||||||
aCORSMode, nsContentSecurityManager::CORSSecurityMapping::
|
|
||||||
CORS_NONE_MAPS_TO_DISABLED_CORS_CHECKS);
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(false, "Unexpected ASDestination");
|
|
||||||
return nsContentSecurityManager::ComputeSecurityFlags(
|
|
||||||
CORSMode::CORS_NONE,
|
|
||||||
nsContentSecurityManager::CORSSecurityMapping::REQUIRE_CORS_CHECKS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void EarlyHintPreloader::MaybeCreateAndInsertPreload(
|
void EarlyHintPreloader::MaybeCreateAndInsertPreload(
|
||||||
OngoingEarlyHints* aOngoingEarlyHints, const LinkHeader& aHeader,
|
OngoingEarlyHints* aOngoingEarlyHints, const LinkHeader& aHeader,
|
||||||
@@ -162,18 +96,19 @@ void EarlyHintPreloader::MaybeCreateAndInsertPreload(
|
|||||||
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
// use the base uri
|
// use the base uri
|
||||||
NS_ENSURE_SUCCESS_VOID(aHeader.NewResolveHref(getter_AddRefs(uri), aBaseURI));
|
NS_ENSURE_SUCCESS_VOID(
|
||||||
|
NS_NewURI(getter_AddRefs(uri), aHeader.mHref, nullptr, aBaseURI));
|
||||||
|
|
||||||
// only preload secure context urls
|
// Only make same origin preloads, the fromPrivateWindow is only read when
|
||||||
if (!uri->SchemeIs("https")) {
|
// reportError is enabled, so setting both to false is safe.
|
||||||
|
if (NS_FAILED(nsContentUtils::GetSecurityManager()->CheckSameOriginURI(
|
||||||
|
aBaseURI, uri, /* reportError */ false,
|
||||||
|
/* fromPrivateWindow */ false))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CORSMode corsMode = dom::Element::StringToCORSMode(aHeader.mCrossOrigin);
|
Maybe<PreloadHashKey> hashKey = GenerateHashKey(
|
||||||
|
static_cast<ASDestination>(as.GetEnumValue()), uri, aTriggeringPrincipal);
|
||||||
Maybe<PreloadHashKey> hashKey =
|
|
||||||
GenerateHashKey(static_cast<ASDestination>(as.GetEnumValue()), uri,
|
|
||||||
aTriggeringPrincipal, corsMode, aHeader.mType);
|
|
||||||
if (!hashKey) {
|
if (!hashKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -197,9 +132,8 @@ void EarlyHintPreloader::MaybeCreateAndInsertPreload(
|
|||||||
RefPtr<EarlyHintPreloader> earlyHintPreloader =
|
RefPtr<EarlyHintPreloader> earlyHintPreloader =
|
||||||
RefPtr(new EarlyHintPreloader(uri));
|
RefPtr(new EarlyHintPreloader(uri));
|
||||||
|
|
||||||
nsSecurityFlags securityFlags = EarlyHintPreloader::ComputeSecurityFlags(
|
nsSecurityFlags securityFlags =
|
||||||
corsMode, static_cast<ASDestination>(as.GetEnumValue()),
|
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT;
|
||||||
aHeader.mType.LowerCaseEqualsASCII("module"));
|
|
||||||
|
|
||||||
NS_ENSURE_SUCCESS_VOID(earlyHintPreloader->OpenChannel(
|
NS_ENSURE_SUCCESS_VOID(earlyHintPreloader->OpenChannel(
|
||||||
aTriggeringPrincipal, securityFlags, contentPolicyType, referrerInfo,
|
aTriggeringPrincipal, securityFlags, contentPolicyType, referrerInfo,
|
||||||
@@ -214,12 +148,7 @@ nsresult EarlyHintPreloader::OpenChannel(
|
|||||||
nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags,
|
nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags,
|
||||||
nsContentPolicyType aContentPolicyType, nsIReferrerInfo* aReferrerInfo,
|
nsContentPolicyType aContentPolicyType, nsIReferrerInfo* aReferrerInfo,
|
||||||
nsICookieJarSettings* aCookieJarSettings) {
|
nsICookieJarSettings* aCookieJarSettings) {
|
||||||
MOZ_ASSERT(aContentPolicyType == nsContentPolicyType::TYPE_IMAGE ||
|
MOZ_ASSERT(aContentPolicyType == nsContentPolicyType::TYPE_IMAGE);
|
||||||
aContentPolicyType ==
|
|
||||||
nsContentPolicyType::TYPE_INTERNAL_FETCH_PRELOAD ||
|
|
||||||
aContentPolicyType == nsContentPolicyType::TYPE_SCRIPT ||
|
|
||||||
aContentPolicyType == nsContentPolicyType::TYPE_STYLESHEET ||
|
|
||||||
aContentPolicyType == nsContentPolicyType::TYPE_FONT);
|
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
NS_NewChannel(getter_AddRefs(mChannel), mURI, aTriggeringPrincipal,
|
NS_NewChannel(getter_AddRefs(mChannel), mURI, aTriggeringPrincipal,
|
||||||
aSecurityFlags, aContentPolicyType, aCookieJarSettings,
|
aSecurityFlags, aContentPolicyType, aCookieJarSettings,
|
||||||
@@ -321,8 +250,12 @@ EarlyHintPreloader::AsyncOnChannelRedirect(
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// abort the request if redirecting to insecure context
|
// abort the request if redirecting to cross origin resource, the
|
||||||
if (!newURI->SchemeIs("https")) {
|
// fromPrivateWindow is only read when reportError is enabled, so setting both
|
||||||
|
// to false is safe.
|
||||||
|
if (NS_FAILED(nsContentUtils::GetSecurityManager()->CheckSameOriginURI(
|
||||||
|
mURI, newURI, /* reportError */ false,
|
||||||
|
/* fromPrivateWindow */ false))) {
|
||||||
callback->OnRedirectVerifyCallback(NS_ERROR_ABORT);
|
callback->OnRedirectVerifyCallback(NS_ERROR_ABORT);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,13 +72,7 @@ class EarlyHintPreloader final : public nsIStreamListener,
|
|||||||
~EarlyHintPreloader() = default;
|
~EarlyHintPreloader() = default;
|
||||||
|
|
||||||
static Maybe<PreloadHashKey> GenerateHashKey(ASDestination aAs, nsIURI* aURI,
|
static Maybe<PreloadHashKey> GenerateHashKey(ASDestination aAs, nsIURI* aURI,
|
||||||
nsIPrincipal* aPrincipal,
|
nsIPrincipal* aPrincipal);
|
||||||
CORSMode corsMode,
|
|
||||||
const nsAString& aType);
|
|
||||||
|
|
||||||
static nsSecurityFlags ComputeSecurityFlags(CORSMode aCORSMode,
|
|
||||||
ASDestination aAs,
|
|
||||||
bool aIsModule);
|
|
||||||
|
|
||||||
// call to start the preload
|
// call to start the preload
|
||||||
nsresult OpenChannel(nsIPrincipal* aTriggeringPrincipal,
|
nsresult OpenChannel(nsIPrincipal* aTriggeringPrincipal,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<img src="https://example.com/browser/netwerk/test/browser/square.png" width="100px">
|
<img src="http://example.com/browser/netwerk/test/browser/square.png" width="100px">
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
HTTP 103 Too Early
|
HTTP 103 Too Early
|
||||||
Link: <https://example.com/browser/netwerk/test/browser/square.png>; rel=preload; as=image
|
Link: <http://example.com/browser/netwerk/test/browser/square.png>; rel=preload; as=image
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
<img src="https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs?f5a05cb8-43e6-4868-bc0f-ca453ef87826" width="100px">
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Cache-Control: no-cache
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
HTTP 103 Early Hints
|
|
||||||
Link: <netwerk/test/browser/early_hint_pixel.sjs?f5a05cb8-43e6-4868-bc0f-ca453ef87826>; rel=preload; as=image; anchor="/browser/"
|
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
HTTP 103 Early Hints
|
HTTP 103 Early Hints
|
||||||
Link: <https://example.com/browser/netwerk/test/browser/square.png>; rel=preload; as=image
|
Link: <http://example.com/browser/netwerk/test/browser/square.png>; rel=preload; as=image
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<img src="https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs?1ac2a5e1-90c7-4171-b0f0-676f7d899af3" width="100px">
|
<img src="http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs?1ac2a5e1-90c7-4171-b0f0-676f7d899af3" width="100px">
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
HTTP 103 Too Early
|
HTTP 103 Too Early
|
||||||
Link: <https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs?1ac2a5e1-90c7-4171-b0f0-676f7d899af3>; rel=preload; as=image
|
Link: <http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs?1ac2a5e1-90c7-4171-b0f0-676f7d899af3>; rel=preload; as=image
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ support-files =
|
|||||||
early_hint_redirect.sjs
|
early_hint_redirect.sjs
|
||||||
early_hint_pixel.sjs
|
early_hint_pixel.sjs
|
||||||
early_hint_error.sjs
|
early_hint_error.sjs
|
||||||
early_hint_asset.sjs
|
|
||||||
early_hint_asset_html.sjs
|
|
||||||
post.html
|
post.html
|
||||||
res.css
|
res.css
|
||||||
res.css^headers^
|
res.css^headers^
|
||||||
@@ -44,9 +42,6 @@ support-files =
|
|||||||
103_preload.html^headers^
|
103_preload.html^headers^
|
||||||
no_103_preload.html
|
no_103_preload.html
|
||||||
no_103_preload.html^headers^
|
no_103_preload.html^headers^
|
||||||
103_preload_anchor.html^informationalResponse^
|
|
||||||
103_preload_anchor.html^headers^
|
|
||||||
103_preload_anchor.html
|
|
||||||
103_preload_and_404.html^informationalResponse^
|
103_preload_and_404.html^informationalResponse^
|
||||||
103_preload_and_404.html^headers^
|
103_preload_and_404.html^headers^
|
||||||
103_preload_and_404.html
|
103_preload_and_404.html
|
||||||
@@ -95,6 +90,3 @@ support-files =
|
|||||||
early_hint_preload_test_helper.jsm
|
early_hint_preload_test_helper.jsm
|
||||||
skip-if =
|
skip-if =
|
||||||
os == 'linux' && bits == 64 && !debug # Bug 1744028 and Bug 1746324
|
os == 'linux' && bits == 64 && !debug # Bug 1744028 and Bug 1746324
|
||||||
[browser_103_assets.js]
|
|
||||||
skip-if =
|
|
||||||
os == 'linux' && bits == 64 && !debug # Bug 1744028 and Bug 1746324
|
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
Services.prefs.setBoolPref("network.early-hints.enabled", true);
|
|
||||||
|
|
||||||
// - testName is just there to be printed during Asserts when failing
|
|
||||||
// - asset is the asset type, see early_hint_asset_html.sjs for possible values
|
|
||||||
// - hinted: when true, the server reponds with "103 Early Hints"-header
|
|
||||||
async function test_hint_asset(testName, asset, hinted) {
|
|
||||||
// reset the count
|
|
||||||
let headers = new Headers();
|
|
||||||
headers.append("X-Early-Hint-Count-Start", "");
|
|
||||||
await fetch(
|
|
||||||
"http://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs",
|
|
||||||
{ headers }
|
|
||||||
);
|
|
||||||
|
|
||||||
let requestUrl = `https://example.com/browser/netwerk/test/browser/early_hint_asset_html.sjs?as=${asset}&hinted=${
|
|
||||||
hinted ? "1" : "0"
|
|
||||||
}`;
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
gBrowser,
|
|
||||||
url: requestUrl,
|
|
||||||
waitForLoad: true,
|
|
||||||
},
|
|
||||||
async function() {}
|
|
||||||
);
|
|
||||||
|
|
||||||
let gotRequestCount = await fetch(
|
|
||||||
"http://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs"
|
|
||||||
).then(response => response.json());
|
|
||||||
|
|
||||||
await Assert.deepEqual(
|
|
||||||
gotRequestCount,
|
|
||||||
hinted ? { hinted: 1, normal: 0 } : { hinted: 0, normal: 1 },
|
|
||||||
`${testName} (${asset}): Unexpected amount of requests made`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// preload image
|
|
||||||
add_task(async function test_103_asset_style() {
|
|
||||||
await test_hint_asset("test_103_asset_hinted", "image", true);
|
|
||||||
await test_hint_asset("test_103_asset_normal", "image", false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// preload css
|
|
||||||
add_task(async function test_103_asset_style() {
|
|
||||||
await test_hint_asset("test_103_asset_hinted", "style", true);
|
|
||||||
await test_hint_asset("test_103_asset_normal", "style", false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// preload javascript
|
|
||||||
add_task(async function test_103_asset_javascript() {
|
|
||||||
await test_hint_asset("test_103_asset_hinted", "script", true);
|
|
||||||
await test_hint_asset("test_103_asset_normal", "script", false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// preload fetch
|
|
||||||
add_task(async function test_103_asset_fetch() {
|
|
||||||
await test_hint_asset("test_103_asset_hinted", "fetch", true);
|
|
||||||
await test_hint_asset("test_103_asset_normal", "fetch", false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// preload font
|
|
||||||
add_task(async function test_103_asset_font() {
|
|
||||||
await test_hint_asset("test_103_asset_hinted", "font", true);
|
|
||||||
await test_hint_asset("test_103_asset_normal", "font", false);
|
|
||||||
});
|
|
||||||
@@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
Services.prefs.setCharPref(
|
||||||
|
"dom.securecontext.allowlist",
|
||||||
|
"example.com,example.net"
|
||||||
|
);
|
||||||
|
|
||||||
Services.prefs.setBoolPref("network.early-hints.enabled", true);
|
Services.prefs.setBoolPref("network.early-hints.enabled", true);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -18,8 +23,8 @@ const {
|
|||||||
add_task(async function test_103_error_400() {
|
add_task(async function test_103_error_400() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_400",
|
"test_103_error_400",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?400",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?400",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -28,8 +33,8 @@ add_task(async function test_103_error_400() {
|
|||||||
add_task(async function test_103_error_401() {
|
add_task(async function test_103_error_401() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_401",
|
"test_103_error_401",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?401",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?401",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -38,8 +43,8 @@ add_task(async function test_103_error_401() {
|
|||||||
add_task(async function test_103_error_403() {
|
add_task(async function test_103_error_403() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_403",
|
"test_103_error_403",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?403",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?403",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -48,8 +53,8 @@ add_task(async function test_103_error_403() {
|
|||||||
add_task(async function test_103_error_404() {
|
add_task(async function test_103_error_404() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_404",
|
"test_103_error_404",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?404",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?404",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -58,8 +63,8 @@ add_task(async function test_103_error_404() {
|
|||||||
add_task(async function test_103_error_408() {
|
add_task(async function test_103_error_408() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_408",
|
"test_103_error_408",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?408",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?408",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -68,8 +73,8 @@ add_task(async function test_103_error_408() {
|
|||||||
add_task(async function test_103_error_410() {
|
add_task(async function test_103_error_410() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_410",
|
"test_103_error_410",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?410",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?410",
|
||||||
{ hinted: 1, normal: 0 }
|
{ hinted: 1, normal: 0 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -78,8 +83,8 @@ add_task(async function test_103_error_410() {
|
|||||||
add_task(async function test_103_error_429() {
|
add_task(async function test_103_error_429() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_429",
|
"test_103_error_429",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?429",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?429",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -88,8 +93,8 @@ add_task(async function test_103_error_429() {
|
|||||||
add_task(async function test_103_error_500() {
|
add_task(async function test_103_error_500() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_500",
|
"test_103_error_500",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?500",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?500",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -98,8 +103,8 @@ add_task(async function test_103_error_500() {
|
|||||||
add_task(async function test_103_error_502() {
|
add_task(async function test_103_error_502() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_502",
|
"test_103_error_502",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?502",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?502",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -108,8 +113,8 @@ add_task(async function test_103_error_502() {
|
|||||||
add_task(async function test_103_error_503() {
|
add_task(async function test_103_error_503() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_503",
|
"test_103_error_503",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?503",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?503",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -118,8 +123,8 @@ add_task(async function test_103_error_503() {
|
|||||||
add_task(async function test_103_error_504() {
|
add_task(async function test_103_error_504() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_error_504",
|
"test_103_error_504",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_error.sjs?504",
|
"http://example.com/browser/netwerk/test/browser/early_hint_error.sjs?504",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
Services.prefs.setCharPref(
|
||||||
|
"dom.securecontext.allowlist",
|
||||||
|
"example.com,example.net"
|
||||||
|
);
|
||||||
|
|
||||||
Services.prefs.setBoolPref("network.early-hints.enabled", true);
|
Services.prefs.setBoolPref("network.early-hints.enabled", true);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -21,15 +26,15 @@ const {
|
|||||||
add_task(async function test_103_two_preload_responses() {
|
add_task(async function test_103_two_preload_responses() {
|
||||||
await test_hint_preload_internal(
|
await test_hint_preload_internal(
|
||||||
"103_two_preload_responses",
|
"103_two_preload_responses",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
Services.uuid.generateUUID().toString(),
|
Services.uuid.generateUUID().toString(),
|
||||||
],
|
],
|
||||||
["", "new_response"], // empty string to indicate new early hint response
|
["", "new_response"], // empty string to indicate new early hint response
|
||||||
[
|
[
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
Services.uuid.generateUUID().toString(),
|
Services.uuid.generateUUID().toString(),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@@ -41,15 +46,15 @@ add_task(async function test_103_two_preload_responses() {
|
|||||||
add_task(async function test_103_two_link_header() {
|
add_task(async function test_103_two_link_header() {
|
||||||
await test_hint_preload_internal(
|
await test_hint_preload_internal(
|
||||||
"103_two_link_header",
|
"103_two_link_header",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
Services.uuid.generateUUID().toString(),
|
Services.uuid.generateUUID().toString(),
|
||||||
],
|
],
|
||||||
["", ""], // empty string to indicate new early hint response
|
["", ""], // empty string to indicate new early hint response
|
||||||
[
|
[
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
Services.uuid.generateUUID().toString(),
|
Services.uuid.generateUUID().toString(),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@@ -61,14 +66,14 @@ add_task(async function test_103_two_link_header() {
|
|||||||
add_task(async function test_103_two_links() {
|
add_task(async function test_103_two_links() {
|
||||||
await test_hint_preload_internal(
|
await test_hint_preload_internal(
|
||||||
"103_two_links",
|
"103_two_links",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
Services.uuid.generateUUID().toString(),
|
Services.uuid.generateUUID().toString(),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
Services.uuid.generateUUID().toString(),
|
Services.uuid.generateUUID().toString(),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@@ -83,15 +88,15 @@ add_task(async function test_103_preload_twice() {
|
|||||||
let uuid = Services.uuid.generateUUID();
|
let uuid = Services.uuid.generateUUID();
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_preload_twice_1",
|
"test_103_preload_twice_1",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 1, normal: 0 },
|
{ hinted: 1, normal: 0 },
|
||||||
uuid
|
uuid
|
||||||
);
|
);
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_preload_twice_2",
|
"test_103_preload_twice_2",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 0, normal: 0 },
|
{ hinted: 0, normal: 0 },
|
||||||
uuid
|
uuid
|
||||||
);
|
);
|
||||||
@@ -102,8 +107,8 @@ add_task(async function test_103_preload_disabled() {
|
|||||||
Services.prefs.setBoolPref("network.early-hints.enabled", false);
|
Services.prefs.setBoolPref("network.early-hints.enabled", false);
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_preload_disabled",
|
"test_103_preload_disabled",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 0, normal: 1 }
|
{ hinted: 0, normal: 1 }
|
||||||
);
|
);
|
||||||
Services.prefs.setBoolPref("network.early-hints.enabled", true);
|
Services.prefs.setBoolPref("network.early-hints.enabled", true);
|
||||||
@@ -123,8 +128,8 @@ add_task(async function test_103_preload_https() {
|
|||||||
add_task(async function test_103_preload() {
|
add_task(async function test_103_preload() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_preload",
|
"test_103_preload",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 1, normal: 0 }
|
{ hinted: 1, normal: 0 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -133,9 +138,9 @@ add_task(async function test_103_preload() {
|
|||||||
add_task(async function test_103_preload_cor() {
|
add_task(async function test_103_preload_cor() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_preload_cor",
|
"test_103_preload_cor",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.net/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.net/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 1, normal: 0 }
|
{ hinted: 0, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -143,7 +148,7 @@ add_task(async function test_103_preload_cor() {
|
|||||||
add_task(async function test_103_preload_insecure_cor() {
|
add_task(async function test_103_preload_insecure_cor() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_preload_insecure_cor",
|
"test_103_preload_insecure_cor",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"http://mochi.test:8888/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://mochi.test:8888/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 0, normal: 1 }
|
{ hinted: 0, normal: 1 }
|
||||||
);
|
);
|
||||||
@@ -153,7 +158,7 @@ add_task(async function test_103_preload_insecure_cor() {
|
|||||||
add_task(async function test_103_relative_preload() {
|
add_task(async function test_103_relative_preload() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_relative_preload",
|
"test_103_relative_preload",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 1, normal: 0 }
|
{ hinted: 1, normal: 0 }
|
||||||
);
|
);
|
||||||
@@ -173,8 +178,8 @@ add_task(async function test_103_insecure_preload() {
|
|||||||
add_task(async function test_103_redirect_same_origin() {
|
add_task(async function test_103_redirect_same_origin() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_redirect_same_origin",
|
"test_103_redirect_same_origin",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_redirect.sjs?https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_redirect.sjs?http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 2, normal: 0 } // successful preload of redirect and resulting image
|
{ hinted: 2, normal: 0 } // successful preload of redirect and resulting image
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -183,9 +188,9 @@ add_task(async function test_103_redirect_same_origin() {
|
|||||||
add_task(async function test_103_redirect_cross_origin() {
|
add_task(async function test_103_redirect_cross_origin() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_redirect_cross_origin",
|
"test_103_redirect_cross_origin",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_redirect.sjs?https://example.net/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_redirect.sjs?http://example.net/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 2, normal: 0 } // successful load of redirect in preload, but image loaded via normal load
|
{ hinted: 1, normal: 1 } // successful load of redirect in preload, but image loaded via normal load
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -193,8 +198,8 @@ add_task(async function test_103_redirect_cross_origin() {
|
|||||||
add_task(async function test_103_redirect_insecure_cross_origin() {
|
add_task(async function test_103_redirect_insecure_cross_origin() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_redirect_insecure_cross_origin",
|
"test_103_redirect_insecure_cross_origin",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_redirect.sjs?http://mochi.test:8888/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_redirect.sjs?http://mochi.test:8888/browser/netwerk/test/browser/early_hint_pixel.sjs",
|
||||||
{ hinted: 1, normal: 1 }
|
{ hinted: 1, normal: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -223,7 +228,7 @@ add_task(async function test_103_preload_redirect_mixed_content() {
|
|||||||
add_task(async function test_103_preload_only_file() {
|
add_task(async function test_103_preload_only_file() {
|
||||||
await test_hint_preload(
|
await test_hint_preload(
|
||||||
"test_103_preload_only_file",
|
"test_103_preload_only_file",
|
||||||
"https://example.com",
|
"http://example.com",
|
||||||
"early_hint_pixel.sjs",
|
"early_hint_pixel.sjs",
|
||||||
{ hinted: 1, normal: 0 }
|
{ hinted: 1, normal: 0 }
|
||||||
);
|
);
|
||||||
@@ -235,12 +240,12 @@ add_task(async function test_preload_csp_imgsrc_none() {
|
|||||||
let headers = new Headers();
|
let headers = new Headers();
|
||||||
headers.append("X-Early-Hint-Count-Start", "");
|
headers.append("X-Early-Hint-Count-Start", "");
|
||||||
await fetch(
|
await fetch(
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs",
|
||||||
{ headers }
|
{ headers }
|
||||||
);
|
);
|
||||||
|
|
||||||
let requestUrl =
|
let requestUrl =
|
||||||
"https://example.com/browser/netwerk/test/browser/103_preload_csp_imgsrc_none.html";
|
"http://example.com/browser/netwerk/test/browser/103_preload_csp_imgsrc_none.html";
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
await BrowserTestUtils.withNewTab(
|
||||||
{
|
{
|
||||||
@@ -251,7 +256,7 @@ add_task(async function test_preload_csp_imgsrc_none() {
|
|||||||
async function(browser) {
|
async function(browser) {
|
||||||
let noImgLoaded = await SpecialPowers.spawn(browser, [], function() {
|
let noImgLoaded = await SpecialPowers.spawn(browser, [], function() {
|
||||||
let loadInfo = content.performance.getEntriesByName(
|
let loadInfo = content.performance.getEntriesByName(
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs?1ac2a5e1-90c7-4171-b0f0-676f7d899af3"
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel.sjs?1ac2a5e1-90c7-4171-b0f0-676f7d899af3"
|
||||||
);
|
);
|
||||||
return loadInfo.every(entry => entry.decodedBodySize === 0);
|
return loadInfo.every(entry => entry.decodedBodySize === 0);
|
||||||
});
|
});
|
||||||
@@ -263,7 +268,7 @@ add_task(async function test_preload_csp_imgsrc_none() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let gotRequestCount = await fetch(
|
let gotRequestCount = await fetch(
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs"
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs"
|
||||||
).then(response => response.json());
|
).then(response => response.json());
|
||||||
let expectedRequestCount = { hinted: 1, normal: 0 };
|
let expectedRequestCount = { hinted: 1, normal: 0 };
|
||||||
|
|
||||||
@@ -290,12 +295,12 @@ add_task(async function test_103_iframe() {
|
|||||||
let headers = new Headers();
|
let headers = new Headers();
|
||||||
headers.append("X-Early-Hint-Count-Start", "");
|
headers.append("X-Early-Hint-Count-Start", "");
|
||||||
await fetch(
|
await fetch(
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs",
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs",
|
||||||
{ headers }
|
{ headers }
|
||||||
);
|
);
|
||||||
|
|
||||||
let iframeUri =
|
let iframeUri =
|
||||||
"https://example.com/browser/netwerk/test/browser/103_preload_iframe.html";
|
"http://example.com/browser/netwerk/test/browser/103_preload_iframe.html";
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
await BrowserTestUtils.withNewTab(
|
||||||
{
|
{
|
||||||
@@ -307,7 +312,7 @@ add_task(async function test_103_iframe() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let gotRequestCount = await fetch(
|
let gotRequestCount = await fetch(
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs"
|
"http://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs"
|
||||||
).then(response => response.json());
|
).then(response => response.json());
|
||||||
let expectedRequestCount = { hinted: 0, normal: 1 };
|
let expectedRequestCount = { hinted: 0, normal: 1 };
|
||||||
|
|
||||||
@@ -327,36 +332,3 @@ add_task(async function test_103_iframe() {
|
|||||||
|
|
||||||
Services.cache2.clear();
|
Services.cache2.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test that anchors are parsed
|
|
||||||
add_task(async function test_103_anchor() {
|
|
||||||
// reset the count
|
|
||||||
let headers = new Headers();
|
|
||||||
headers.append("X-Early-Hint-Count-Start", "");
|
|
||||||
await fetch(
|
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs",
|
|
||||||
{ headers }
|
|
||||||
);
|
|
||||||
|
|
||||||
let anchorUri =
|
|
||||||
"https://example.com/browser/netwerk/test/browser/103_preload_anchor.html";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
gBrowser,
|
|
||||||
url: anchorUri,
|
|
||||||
waitForLoad: true,
|
|
||||||
},
|
|
||||||
async function() {}
|
|
||||||
);
|
|
||||||
|
|
||||||
let gotRequestCount = await fetch(
|
|
||||||
"https://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs"
|
|
||||||
).then(response => response.json());
|
|
||||||
|
|
||||||
await Assert.deepEqual(
|
|
||||||
gotRequestCount,
|
|
||||||
{ hinted: 1, normal: 0 },
|
|
||||||
"test_103_anchor: Unexpected amount of requests made"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
function handleRequest(request, response) {
|
|
||||||
let hinted =
|
|
||||||
request.hasHeader("X-Moz") && request.getHeader("X-Moz") === "early hint";
|
|
||||||
let count = JSON.parse(getSharedState("earlyHintCount"));
|
|
||||||
if (hinted) {
|
|
||||||
count.hinted += 1;
|
|
||||||
} else {
|
|
||||||
count.normal += 1;
|
|
||||||
}
|
|
||||||
setSharedState("earlyHintCount", JSON.stringify(count));
|
|
||||||
response.setHeader("Cache-Control", "max-age=604800", false);
|
|
||||||
|
|
||||||
let content = "";
|
|
||||||
Cu.importGlobalProperties(["URLSearchParams"]);
|
|
||||||
let qs = new URLSearchParams(request.queryString);
|
|
||||||
let asset = qs.get("as");
|
|
||||||
|
|
||||||
if (asset === "image") {
|
|
||||||
response.setHeader("Content-Type", "image/png", false);
|
|
||||||
// set to green/black horizontal stripes (71 bytes)
|
|
||||||
content = atob(
|
|
||||||
hinted
|
|
||||||
? "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAADklEQVQIW2OU+i/FAAcADoABNV8XGBMAAAAASUVORK5CYII="
|
|
||||||
: "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAE0lEQVQIW2P4//+/N8MkBiAGsgA1bAe1SzDY8gAAAABJRU5ErkJggg=="
|
|
||||||
);
|
|
||||||
} else if (asset === "style") {
|
|
||||||
response.setHeader("Content-Type", "text/css", false);
|
|
||||||
// green background on hint response, purple response otherwise
|
|
||||||
content = `#square { background: ${hinted ? "#1aff1a" : "#4b0092"}`;
|
|
||||||
} else if (asset === "script") {
|
|
||||||
response.setHeader("Content-Type", "application/javascript", false);
|
|
||||||
// green background on hint response, purple response otherwise
|
|
||||||
content = `window.onload = function() {
|
|
||||||
document.getElementById('square').style.background = "${
|
|
||||||
hinted ? "#1aff1a" : "#4b0092"
|
|
||||||
}";
|
|
||||||
}`;
|
|
||||||
} else if (asset === "fetch") {
|
|
||||||
response.setHeader("Content-Type", "text/plain", false);
|
|
||||||
content = hinted ? "hinted" : "normal";
|
|
||||||
}
|
|
||||||
|
|
||||||
response.write(content);
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
function handleRequest(request, response) {
|
|
||||||
Cu.importGlobalProperties(["URLSearchParams"]);
|
|
||||||
let qs = new URLSearchParams(request.queryString);
|
|
||||||
let asset = qs.get("as");
|
|
||||||
let hinted = qs.get("hinted") !== "0";
|
|
||||||
|
|
||||||
// eslint-disable-next-line mozilla/use-services
|
|
||||||
let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(
|
|
||||||
Ci.nsIUUIDGenerator
|
|
||||||
);
|
|
||||||
let uuid = uuidGenerator.generateUUID().toString();
|
|
||||||
let url = `early_hint_asset.sjs?as=${asset}&uuid=${uuid}`;
|
|
||||||
|
|
||||||
// write to raw socket
|
|
||||||
response.seizePower();
|
|
||||||
|
|
||||||
if (hinted) {
|
|
||||||
response.write("HTTP/1.1 103 Early Hint\r\n");
|
|
||||||
response.write(`Link: <${url}>; rel=preload; as=${asset}\r\n`);
|
|
||||||
response.write("\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
let body = "";
|
|
||||||
if (asset === "image") {
|
|
||||||
body = `<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
<img src="${url}" width="100px">
|
|
||||||
</body>
|
|
||||||
</html>`;
|
|
||||||
} else if (asset === "style") {
|
|
||||||
body = `<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" type="text/css" href="${url}">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Test preload css<h1>
|
|
||||||
<div id="square" style="width:100px;height:100px;">
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
} else if (asset === "script") {
|
|
||||||
body = `<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script src="${url}"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Test preload javascript<h1>
|
|
||||||
<div id="square" style="width:100px;height:100px;">
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
} else if (asset === "fetch") {
|
|
||||||
body = `<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<body onload="onLoad()">
|
|
||||||
<script>
|
|
||||||
function onLoad() {
|
|
||||||
fetch("${url}")
|
|
||||||
.then(r => r.text())
|
|
||||||
.then(r => document.getElementsByTagName("h2")[0].textContent = r);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<h1>Test preload fetch</h1>
|
|
||||||
<h2>Fetching...</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
} else if (asset === "font") {
|
|
||||||
body = `<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<style>
|
|
||||||
@font-face {
|
|
||||||
font-family: "preloadFont";
|
|
||||||
src: url("${url}") format("woff");
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
font-family: "preloadFont";
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Test preload font<h1>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// main document response
|
|
||||||
response.write("HTTP/1.1 200 OK\r\n");
|
|
||||||
response.write("Content-Type: text/html;charset=utf-8\r\n");
|
|
||||||
response.write("Cache-Control: no-cache\r\n");
|
|
||||||
response.write(`Content-Length: ${body.length}\r\n`);
|
|
||||||
response.write("\r\n");
|
|
||||||
response.write(body);
|
|
||||||
response.finish();
|
|
||||||
}
|
|
||||||
@@ -243,64 +243,3 @@ const SimpleParseTestData simple_parse_tests[] = {
|
|||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(TestLinkHeader, SimpleParseTest,
|
INSTANTIATE_TEST_SUITE_P(TestLinkHeader, SimpleParseTest,
|
||||||
testing::ValuesIn(simple_parse_tests));
|
testing::ValuesIn(simple_parse_tests));
|
||||||
|
|
||||||
// Test anchor
|
|
||||||
|
|
||||||
struct AnchorTestData {
|
|
||||||
nsString baseURI;
|
|
||||||
// building the new anchor in combination with the baseURI
|
|
||||||
nsString anchor;
|
|
||||||
nsString href;
|
|
||||||
const char* resolved;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AnchorTest : public ::testing::TestWithParam<AnchorTestData> {};
|
|
||||||
|
|
||||||
const AnchorTestData anchor_tests[] = {
|
|
||||||
{u"http://example.com/path/to/index.html"_ns, u""_ns, u"page.html"_ns,
|
|
||||||
"http://example.com/path/to/page.html"},
|
|
||||||
{u"http://example.com/path/to/index.html"_ns,
|
|
||||||
u"http://example.com/path/"_ns, u"page.html"_ns,
|
|
||||||
"http://example.com/path/page.html"},
|
|
||||||
{u"http://example.com/path/to/index.html"_ns,
|
|
||||||
u"http://example.com/path/"_ns, u"/page.html"_ns,
|
|
||||||
"http://example.com/page.html"},
|
|
||||||
{u"http://example.com/path/to/index.html"_ns, u".."_ns, u"page.html"_ns,
|
|
||||||
"http://example.com/path/page.html"},
|
|
||||||
{u"http://example.com/path/to/index.html"_ns, u".."_ns,
|
|
||||||
u"from/page.html"_ns, "http://example.com/path/from/page.html"},
|
|
||||||
{u"http://example.com/path/to/index.html"_ns, u"/hello/"_ns,
|
|
||||||
u"page.html"_ns, "http://example.com/hello/page.html"},
|
|
||||||
{u"http://example.com/path/to/index.html"_ns, u"/hello"_ns, u"page.html"_ns,
|
|
||||||
"http://example.com/page.html"},
|
|
||||||
{u"http://example.com/path/to/index.html"_ns, u"#necko"_ns, u"page.html"_ns,
|
|
||||||
"http://example.com/path/to/page.html"},
|
|
||||||
{u"http://example.com/path/to/index.html"_ns, u"https://example.net/"_ns,
|
|
||||||
u"to/page.html"_ns, "https://example.net/to/page.html"},
|
|
||||||
};
|
|
||||||
|
|
||||||
LinkHeader LinkHeaderFromHrefAndAnchor(nsAString const& aHref,
|
|
||||||
nsAString const& aAnchor) {
|
|
||||||
LinkHeader l;
|
|
||||||
l.mHref = aHref;
|
|
||||||
l.mAnchor = aAnchor;
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AnchorTest, Anchor) {
|
|
||||||
const AnchorTestData test = GetParam();
|
|
||||||
|
|
||||||
LinkHeader linkHeader = LinkHeaderFromHrefAndAnchor(test.href, test.anchor);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> baseURI;
|
|
||||||
ASSERT_TRUE(NS_SUCCEEDED(NS_NewURI(getter_AddRefs(baseURI), test.baseURI)));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> resolved;
|
|
||||||
ASSERT_TRUE(NS_SUCCEEDED(
|
|
||||||
linkHeader.NewResolveHref(getter_AddRefs(resolved), baseURI)));
|
|
||||||
|
|
||||||
ASSERT_STREQ(resolved->GetSpecOrDefault().get(), test.resolved);
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(TestLinkHeader, AnchorTest,
|
|
||||||
testing::ValuesIn(anchor_tests));
|
|
||||||
|
|||||||
@@ -7,14 +7,12 @@
|
|||||||
|
|
||||||
#include "FetchPreloader.h"
|
#include "FetchPreloader.h"
|
||||||
|
|
||||||
#include "mozilla/CORSMode.h"
|
|
||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "mozilla/LoadInfo.h"
|
#include "mozilla/LoadInfo.h"
|
||||||
#include "mozilla/ScopeExit.h"
|
#include "mozilla/ScopeExit.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "nsContentPolicyUtils.h"
|
#include "nsContentPolicyUtils.h"
|
||||||
#include "nsContentSecurityManager.h"
|
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIChannel.h"
|
#include "nsIChannel.h"
|
||||||
#include "nsIClassOfService.h"
|
#include "nsIClassOfService.h"
|
||||||
@@ -88,9 +86,14 @@ nsresult FetchPreloader::CreateChannel(
|
|||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsSecurityFlags securityFlags =
|
nsSecurityFlags securityFlags =
|
||||||
nsContentSecurityManager::ComputeSecurityFlags(
|
aCORSMode == CORS_NONE
|
||||||
aCORSMode, nsContentSecurityManager::CORSSecurityMapping::
|
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
|
||||||
CORS_NONE_MAPS_TO_DISABLED_CORS_CHECKS);
|
: nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT;
|
||||||
|
if (aCORSMode == CORS_ANONYMOUS) {
|
||||||
|
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||||
|
} else if (aCORSMode == CORS_USE_CREDENTIALS) {
|
||||||
|
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> channel;
|
nsCOMPtr<nsIChannel> channel;
|
||||||
rv = NS_NewChannelWithTriggeringPrincipal(
|
rv = NS_NewChannelWithTriggeringPrincipal(
|
||||||
|
|||||||
Reference in New Issue
Block a user