зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1670617 - Part 2: Make the CORS preflight cache partitioned by the originAttributes. r=ckerschb,necko-reviewers
We want to partition the CORS preflight cache by the network state partitioning. So, we have done two things in the patch. First, we make the CORS preflight cache to be aware of the OriginAttributes. Second, we use the originAttributes of the network state partitioning in the CORS preflight cache. As the result, the CORS preflight cache will be partitioned by the originAttributes.partitionKey as well as other originAttributes fields if present. Differential Revision: https://phabricator.services.mozilla.com/D93683
This commit is contained in:
Родитель
2546d22172
Коммит
18853bea78
|
@ -671,6 +671,7 @@ BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI, bool* aRes) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
nsACString& _retval) {
|
||||
_retval.Truncate();
|
||||
constexpr auto space = " "_ns;
|
||||
|
@ -696,7 +697,11 @@ BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
|
|||
rv = aURI->GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
_retval.Append(space + scheme + space + host + space + port + space + spec);
|
||||
nsAutoCString originAttributesSuffix;
|
||||
aOriginAttributes.CreateSuffix(originAttributesSuffix);
|
||||
|
||||
_retval.Append(space + scheme + space + host + space + port + space + spec +
|
||||
space + originAttributesSuffix);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -154,6 +154,7 @@ class BasePrincipal : public nsJSPrincipals {
|
|||
NS_IMETHOD IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin,
|
||||
bool* aRes) override;
|
||||
NS_IMETHOD GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
nsACString& _retval) override;
|
||||
NS_IMETHOD HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow,
|
||||
uint32_t* aRejectedReason,
|
||||
|
|
|
@ -341,7 +341,9 @@ interface nsIPrincipal : nsISerializable
|
|||
/*
|
||||
* Generates a Cache-Key for the Cors-Preflight Cache
|
||||
*/
|
||||
ACString getPrefLightCacheKey(in nsIURI aURI ,in bool aWithCredentials);
|
||||
[noscript]
|
||||
ACString getPrefLightCacheKey(in nsIURI aURI ,in bool aWithCredentials,
|
||||
in const_OriginAttributes aOriginAttributes);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -2761,8 +2761,9 @@ void HttpChannelChild::GetClientSetCorsPreflightParameters(
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::RemoveCorsPreflightCacheEntry(nsIURI* aURI,
|
||||
nsIPrincipal* aPrincipal) {
|
||||
HttpChannelChild::RemoveCorsPreflightCacheEntry(
|
||||
nsIURI* aURI, nsIPrincipal* aPrincipal,
|
||||
const OriginAttributes& aOriginAttributes) {
|
||||
URIParams uri;
|
||||
SerializeURI(aURI, uri);
|
||||
PrincipalInfo principalInfo;
|
||||
|
@ -2774,7 +2775,8 @@ HttpChannelChild::RemoveCorsPreflightCacheEntry(nsIURI* aURI,
|
|||
// Be careful to not attempt to send a message to the parent after the
|
||||
// actor has been destroyed.
|
||||
if (CanSend()) {
|
||||
result = SendRemoveCorsPreflightCacheEntry(uri, principalInfo);
|
||||
result = SendRemoveCorsPreflightCacheEntry(uri, principalInfo,
|
||||
aOriginAttributes);
|
||||
}
|
||||
return result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -1045,7 +1045,8 @@ HttpChannelParent::RecvMarkOfflineCacheEntryAsForeign() {
|
|||
|
||||
mozilla::ipc::IPCResult HttpChannelParent::RecvRemoveCorsPreflightCacheEntry(
|
||||
const URIParams& uri,
|
||||
const mozilla::ipc::PrincipalInfo& requestingPrincipal) {
|
||||
const mozilla::ipc::PrincipalInfo& requestingPrincipal,
|
||||
const OriginAttributes& originAttributes) {
|
||||
nsCOMPtr<nsIURI> deserializedURI = DeserializeURI(uri);
|
||||
if (!deserializedURI) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
|
@ -1055,7 +1056,8 @@ mozilla::ipc::IPCResult HttpChannelParent::RecvRemoveCorsPreflightCacheEntry(
|
|||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
nsCOMPtr<nsIPrincipal> principal = principalOrErr.unwrap();
|
||||
nsCORSListenerProxy::RemoveFromCorsPreflightCache(deserializedURI, principal);
|
||||
nsCORSListenerProxy::RemoveFromCorsPreflightCache(deserializedURI, principal,
|
||||
originAttributes);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -195,7 +195,8 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
|
|||
virtual mozilla::ipc::IPCResult RecvMarkOfflineCacheEntryAsForeign() override;
|
||||
virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(
|
||||
const URIParams& uri,
|
||||
const mozilla::ipc::PrincipalInfo& requestingPrincipal) override;
|
||||
const mozilla::ipc::PrincipalInfo& requestingPrincipal,
|
||||
const OriginAttributes& originAttributes) override;
|
||||
virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override;
|
||||
virtual mozilla::ipc::IPCResult RecvOpenOriginalCacheInputStream() override;
|
||||
virtual mozilla::ipc::IPCResult RecvOpenAltDataCacheInputStream(
|
||||
|
|
|
@ -16,6 +16,8 @@ include HttpChannelParams;
|
|||
|
||||
include "mozilla/net/NeckoMessageUtils.h";
|
||||
|
||||
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
|
@ -69,7 +71,8 @@ parent:
|
|||
// Child has detected a CORS check failure, so needs to tell the parent
|
||||
// to remove any matching entry from the CORS preflight cache.
|
||||
async RemoveCorsPreflightCacheEntry(URIParams uri,
|
||||
PrincipalInfo requestingPrincipal);
|
||||
PrincipalInfo requestingPrincipal,
|
||||
OriginAttributes originAttributes);
|
||||
|
||||
// After receiving this message, the parent calls SendDeleteSelf, and makes
|
||||
// sure not to send any more messages after that.
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/StaticPrefs_content.h"
|
||||
#include "mozilla/StoragePrincipalHelper.h"
|
||||
|
||||
#include "nsCORSListenerProxy.h"
|
||||
#include "nsIChannel.h"
|
||||
|
@ -168,8 +169,10 @@ class nsPreflightCache {
|
|||
bool Initialize() { return true; }
|
||||
|
||||
CacheEntry* GetEntry(nsIURI* aURI, nsIPrincipal* aPrincipal,
|
||||
bool aWithCredentials, bool aCreate);
|
||||
void RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal);
|
||||
bool aWithCredentials,
|
||||
const OriginAttributes& aOriginAttributes, bool aCreate);
|
||||
void RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal,
|
||||
const OriginAttributes& aOriginAttributes);
|
||||
|
||||
void Clear();
|
||||
|
||||
|
@ -243,10 +246,10 @@ bool nsPreflightCache::CacheEntry::CheckRequest(
|
|||
|
||||
nsPreflightCache::CacheEntry* nsPreflightCache::GetEntry(
|
||||
nsIURI* aURI, nsIPrincipal* aPrincipal, bool aWithCredentials,
|
||||
bool aCreate) {
|
||||
const OriginAttributes& aOriginAttributes, bool aCreate) {
|
||||
nsCString key;
|
||||
if (NS_FAILED(
|
||||
aPrincipal->GetPrefLightCacheKey(aURI, aWithCredentials, key))) {
|
||||
if (NS_FAILED(aPrincipal->GetPrefLightCacheKey(aURI, aWithCredentials,
|
||||
aOriginAttributes, key))) {
|
||||
NS_WARNING("Invalid cache key!");
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -313,16 +316,20 @@ nsPreflightCache::CacheEntry* nsPreflightCache::GetEntry(
|
|||
return newEntry;
|
||||
}
|
||||
|
||||
void nsPreflightCache::RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal) {
|
||||
void nsPreflightCache::RemoveEntries(
|
||||
nsIURI* aURI, nsIPrincipal* aPrincipal,
|
||||
const OriginAttributes& aOriginAttributes) {
|
||||
CacheEntry* entry;
|
||||
nsCString key;
|
||||
if (NS_SUCCEEDED(aPrincipal->GetPrefLightCacheKey(aURI, true, key)) &&
|
||||
if (NS_SUCCEEDED(aPrincipal->GetPrefLightCacheKey(aURI, true,
|
||||
aOriginAttributes, key)) &&
|
||||
mTable.Get(key, &entry)) {
|
||||
entry->removeFrom(mList);
|
||||
mTable.Remove(key);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(aPrincipal->GetPrefLightCacheKey(aURI, false, key)) &&
|
||||
if (NS_SUCCEEDED(aPrincipal->GetPrefLightCacheKey(aURI, false,
|
||||
aOriginAttributes, key)) &&
|
||||
mTable.Get(key, &entry)) {
|
||||
entry->removeFrom(mList);
|
||||
mTable.Remove(key);
|
||||
|
@ -396,16 +403,20 @@ nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest) {
|
|||
nsCOMPtr<nsIURI> uri;
|
||||
NS_GetFinalChannelURI(channel, getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
OriginAttributes attrs;
|
||||
StoragePrincipalHelper::GetOriginAttributesForNetworkState(channel,
|
||||
attrs);
|
||||
|
||||
if (sPreflightCache) {
|
||||
// OK to use mRequestingPrincipal since preflights never get
|
||||
// redirected.
|
||||
sPreflightCache->RemoveEntries(uri, mRequestingPrincipal);
|
||||
sPreflightCache->RemoveEntries(uri, mRequestingPrincipal, attrs);
|
||||
} else {
|
||||
nsCOMPtr<nsIHttpChannelChild> httpChannelChild =
|
||||
do_QueryInterface(channel);
|
||||
if (httpChannelChild) {
|
||||
rv = httpChannelChild->RemoveCorsPreflightCacheEntry(
|
||||
uri, mRequestingPrincipal);
|
||||
uri, mRequestingPrincipal, attrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Only warn here to ensure we fall through the request Cancel()
|
||||
// and outer listener OnStartRequest() calls.
|
||||
|
@ -681,16 +692,19 @@ nsCORSListenerProxy::AsyncOnChannelRedirect(
|
|||
nsCOMPtr<nsIURI> oldURI;
|
||||
NS_GetFinalChannelURI(aOldChannel, getter_AddRefs(oldURI));
|
||||
if (oldURI) {
|
||||
OriginAttributes attrs;
|
||||
StoragePrincipalHelper::GetOriginAttributesForNetworkState(aOldChannel,
|
||||
attrs);
|
||||
if (sPreflightCache) {
|
||||
// OK to use mRequestingPrincipal since preflights never get
|
||||
// redirected.
|
||||
sPreflightCache->RemoveEntries(oldURI, mRequestingPrincipal);
|
||||
sPreflightCache->RemoveEntries(oldURI, mRequestingPrincipal, attrs);
|
||||
} else {
|
||||
nsCOMPtr<nsIHttpChannelChild> httpChannelChild =
|
||||
do_QueryInterface(aOldChannel);
|
||||
if (httpChannelChild) {
|
||||
rv = httpChannelChild->RemoveCorsPreflightCacheEntry(
|
||||
oldURI, mRequestingPrincipal);
|
||||
oldURI, mRequestingPrincipal, attrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Only warn here to ensure we call the channel Cancel() below
|
||||
NS_WARNING("Failed to remove CORS preflight cache entry!");
|
||||
|
@ -1120,8 +1134,11 @@ void nsCORSPreflightListener::AddResultToCache(nsIRequest* aRequest) {
|
|||
TimeStamp expirationTime =
|
||||
TimeStamp::NowLoRes() + TimeDuration::FromSeconds(age);
|
||||
|
||||
OriginAttributes attrs;
|
||||
StoragePrincipalHelper::GetOriginAttributesForNetworkState(http, attrs);
|
||||
|
||||
nsPreflightCache::CacheEntry* entry = sPreflightCache->GetEntry(
|
||||
uri, mReferrerPrincipal, mWithCredentials, true);
|
||||
uri, mReferrerPrincipal, mWithCredentials, attrs, true);
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
@ -1357,10 +1374,12 @@ nsCORSPreflightListener::GetInterface(const nsIID& aIID, void** aResult) {
|
|||
}
|
||||
|
||||
void nsCORSListenerProxy::RemoveFromCorsPreflightCache(
|
||||
nsIURI* aURI, nsIPrincipal* aRequestingPrincipal) {
|
||||
nsIURI* aURI, nsIPrincipal* aRequestingPrincipal,
|
||||
const OriginAttributes& aOriginAttributes) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
if (sPreflightCache) {
|
||||
sPreflightCache->RemoveEntries(aURI, aRequestingPrincipal);
|
||||
sPreflightCache->RemoveEntries(aURI, aRequestingPrincipal,
|
||||
aOriginAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1405,7 +1424,11 @@ nsresult nsCORSListenerProxy::StartCORSPreflight(
|
|||
bool disableCache = Preferences::GetBool("devtools.cache.disabled");
|
||||
|
||||
if (sPreflightCache && !disableCache) {
|
||||
entry = sPreflightCache->GetEntry(uri, principal, withCredentials, false);
|
||||
OriginAttributes attrs;
|
||||
StoragePrincipalHelper::GetOriginAttributesForNetworkState(aRequestChannel,
|
||||
attrs);
|
||||
entry = sPreflightCache->GetEntry(uri, principal, withCredentials, attrs,
|
||||
false);
|
||||
}
|
||||
|
||||
if (entry && entry->CheckRequest(method, aUnsafeHeaders)) {
|
||||
|
|
|
@ -79,8 +79,9 @@ class nsCORSListenerProxy final : public nsIStreamListener,
|
|||
// Only nsHttpChannel can invoke CORS preflights
|
||||
friend class mozilla::net::nsHttpChannel;
|
||||
|
||||
static void RemoveFromCorsPreflightCache(nsIURI* aURI,
|
||||
nsIPrincipal* aRequestingPrincipal);
|
||||
static void RemoveFromCorsPreflightCache(
|
||||
nsIURI* aURI, nsIPrincipal* aRequestingPrincipal,
|
||||
const mozilla::OriginAttributes& aOriginAttributes);
|
||||
[[nodiscard]] static nsresult StartCORSPreflight(
|
||||
nsIChannel* aRequestChannel, nsICorsPreflightCallback* aCallback,
|
||||
nsTArray<nsCString>& aACUnsafeHeaders, nsIChannel** aPreflightChannel);
|
||||
|
|
|
@ -5,8 +5,15 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
%{ C++
|
||||
namespace mozilla {
|
||||
class OriginAttributes;
|
||||
} // mozilla namespace
|
||||
%}
|
||||
|
||||
[ptr] native RequestHeaderTuples(mozilla::net::RequestHeaderTuples);
|
||||
[ref] native MaybeCorsPreflightArgsRef(mozilla::Maybe<mozilla::net::CorsPreflightArgs>);
|
||||
[ref] native const_OriginAttributes(const mozilla::OriginAttributes);
|
||||
|
||||
interface nsIPrincipal;
|
||||
interface nsIURI;
|
||||
|
@ -26,5 +33,6 @@ interface nsIHttpChannelChild : nsISupports
|
|||
// This method is called by nsCORSListenerProxy if we need to remove
|
||||
// an entry from the CORS preflight cache in the parent process.
|
||||
[must_use]
|
||||
void removeCorsPreflightCacheEntry(in nsIURI aURI, in nsIPrincipal aRequestingPrincipal);
|
||||
void removeCorsPreflightCacheEntry(in nsIURI aURI, in nsIPrincipal aRequestingPrincipal,
|
||||
in const_OriginAttributes aOriginAttributes);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче