commit 12e8ea415decfa31640e6acbe704e57c1bff7f87
parent 308c182b399c962536c11ff6d3b432ee18ab4b2d
Author: Randell Jesup <rjesup@mozilla.com>
Date: Wed, 1 Oct 2025 18:46:00 +0000
Bug 1917976: Compression Dictionary match-dest support r=necko-reviewers,valentin,kershaw
Differential Revision: https://phabricator.services.mozilla.com/D258169
Diffstat:
8 files changed, 194 insertions(+), 67 deletions(-)
diff --git a/dom/fetch/InternalRequest.cpp b/dom/fetch/InternalRequest.cpp
@@ -260,6 +260,7 @@ void InternalRequest::SetInterceptionContentPolicyType(
}
/* static */
+/* static */
RequestDestination InternalRequest::MapContentPolicyTypeToRequestDestination(
nsContentPolicyType aContentPolicyType) {
switch (aContentPolicyType) {
@@ -368,6 +369,63 @@ RequestDestination InternalRequest::MapContentPolicyTypeToRequestDestination(
return RequestDestination::_empty;
}
+/* static */
+RequestDestination InternalRequest::MapContentPolicyTypeToRequestDestination(
+ ExtContentPolicyType aContentPolicyType) {
+ switch (aContentPolicyType) {
+ case ExtContentPolicyType::TYPE_INVALID:
+ case ExtContentPolicyType::TYPE_OTHER:
+ return RequestDestination::_empty;
+ case ExtContentPolicyType::TYPE_SCRIPT:
+ return RequestDestination::Script;
+ case ExtContentPolicyType::TYPE_IMAGE:
+ return RequestDestination::Image;
+ case ExtContentPolicyType::TYPE_STYLESHEET:
+ return RequestDestination::Style;
+ case ExtContentPolicyType::TYPE_OBJECT:
+ return RequestDestination::Object;
+ case ExtContentPolicyType::TYPE_DOCUMENT:
+ return RequestDestination::Document;
+ case ExtContentPolicyType::TYPE_SUBDOCUMENT:
+ return RequestDestination::Iframe;
+ case ExtContentPolicyType::TYPE_PING:
+ case ExtContentPolicyType::TYPE_XMLHTTPREQUEST:
+ case ExtContentPolicyType::TYPE_DTD:
+ return RequestDestination::_empty;
+ case ExtContentPolicyType::TYPE_FONT:
+ return RequestDestination::Font;
+ case ExtContentPolicyType::TYPE_MEDIA:
+ case ExtContentPolicyType::TYPE_WEBSOCKET:
+ return RequestDestination::_empty;
+ case ExtContentPolicyType::TYPE_CSP_REPORT:
+ return RequestDestination::Report;
+ case ExtContentPolicyType::TYPE_XSLT:
+ return RequestDestination::Xslt;
+ case ExtContentPolicyType::TYPE_BEACON:
+ case ExtContentPolicyType::TYPE_FETCH:
+ return RequestDestination::_empty;
+ case ExtContentPolicyType::TYPE_IMAGESET:
+ return RequestDestination::Image;
+ case ExtContentPolicyType::TYPE_WEB_MANIFEST:
+ return RequestDestination::Manifest;
+ case ExtContentPolicyType::TYPE_SAVEAS_DOWNLOAD:
+ case ExtContentPolicyType::TYPE_SPECULATIVE:
+ return RequestDestination::_empty;
+ case ExtContentPolicyType::TYPE_UA_FONT:
+ return RequestDestination::Font;
+ case ExtContentPolicyType::TYPE_PROXIED_WEBRTC_MEDIA:
+ case ExtContentPolicyType::TYPE_WEB_IDENTITY:
+ case ExtContentPolicyType::TYPE_WEB_TRANSPORT:
+ return RequestDestination::_empty;
+ case ExtContentPolicyType::TYPE_JSON:
+ return RequestDestination::Json;
+ // Do not add default: so that compilers can catch the missing case.
+ }
+
+ MOZ_ASSERT(false, "Unhandled ExContentPolicyType value");
+ return RequestDestination::_empty;
+}
+
// static
bool InternalRequest::IsNavigationContentPolicy(
nsContentPolicyType aContentPolicyType) {
diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h
@@ -426,6 +426,8 @@ class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
// destination.
static RequestDestination MapContentPolicyTypeToRequestDestination(
nsContentPolicyType aContentPolicyType);
+ static RequestDestination MapContentPolicyTypeToRequestDestination(
+ ExtContentPolicyType aContentPolicyType);
private:
static bool IsNavigationContentPolicy(nsContentPolicyType aContentPolicyType);
diff --git a/netwerk/cache2/CacheFileMetadata.cpp b/netwerk/cache2/CacheFileMetadata.cpp
@@ -245,7 +245,8 @@ nsresult CacheFileMetadata::WriteMetadata(
memcpy(p, mBuf, mElementsSize);
p += mElementsSize;
}
-
+ LOG(("CacheFileMetadata::WriteMetadata() [this=%p, key=%s, mElementsSize=%d]",
+ this, mKey.get(), mElementsSize));
CacheHash::Hash32_t hash;
hash = CacheHash::Hash(mWriteBuf + sizeof(uint32_t),
p - mWriteBuf - sizeof(uint32_t));
diff --git a/netwerk/cache2/Dictionary.cpp b/netwerk/cache2/Dictionary.cpp
@@ -8,6 +8,8 @@
#include "Dictionary.h"
#include "CacheFileUtils.h"
+#include "nsAttrValue.h"
+#include "nsContentPolicyUtils.h"
#include "nsString.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIAsyncInputStream.h"
@@ -54,6 +56,7 @@
#include "SerializedLoadContext.h"
#include "mozilla/dom/ContentParent.h"
+#include "mozilla/dom/InternalRequest.h"
#include "mozilla/ClearOnShutdown.h"
#include "ReferrerInfo.h"
@@ -90,9 +93,11 @@ DictionaryCacheEntry::DictionaryCacheEntry(const char* aKey) { mURI = aKey; }
DictionaryCacheEntry::DictionaryCacheEntry(const nsACString& aURI,
const nsACString& aPattern,
+ nsTArray<nsCString>& aMatchDest,
const nsACString& aId,
const Maybe<nsCString>& aHash)
: mURI(aURI), mPattern(aPattern), mId(aId) {
+ ConvertMatchDestToEnumArray(aMatchDest, mMatchDest);
if (aHash) {
mHash = aHash.value();
}
@@ -101,8 +106,26 @@ DictionaryCacheEntry::DictionaryCacheEntry(const nsACString& aURI,
NS_IMPL_ISUPPORTS(DictionaryCacheEntry, nsICacheEntryOpenCallback,
nsIStreamListener)
+// Convert string MatchDest array to enum array
+// static
+void DictionaryCacheEntry::ConvertMatchDestToEnumArray(
+ const nsTArray<nsCString>& aMatchDest,
+ nsTArray<dom::RequestDestination>& aMatchEnums) {
+ AutoTArray<dom::RequestDestination, 3> temp;
+ for (auto& string : aMatchDest) {
+ dom::RequestDestination dest =
+ dom::StringToEnum<dom::RequestDestination>(string).valueOr(
+ dom::RequestDestination::_empty);
+ if (dest != dom::RequestDestination::_empty) {
+ temp.AppendElement(dest);
+ }
+ }
+ aMatchEnums.SwapElements(temp);
+}
+
// returns true if the pattern for the dictionary matches the path given
bool DictionaryCacheEntry::Match(const nsACString& aFilePath,
+ ExtContentPolicyType aType,
uint32_t& aLongest) {
if (mHash.IsEmpty()) {
// We don't have the file yet
@@ -114,34 +137,39 @@ bool DictionaryCacheEntry::Match(const nsACString& aFilePath,
return false;
}
// Not worth checking if we wouldn't use it
- // XXX Check match-dest
+ DICTIONARY_LOG(("Match: %s to %s, %s", PromiseFlatCString(aFilePath).get(),
+ mPattern.get(), NS_CP_ContentTypeName(aType)));
if (mPattern.Length() > aLongest) {
- DICTIONARY_LOG(("Match: %s to %s", PromiseFlatCString(aFilePath).get(),
- PromiseFlatCString(mPattern).get()));
- // XXX remove this when we get URLPattern
- // XXX temp: handle https://site/foo* or https://site/foo?query=*, or
- // https://site/foo/*, etc
- if (mPattern.Last() == '*' && aFilePath.Length() >= mPattern.Length()) {
- // XXX not efficient, but this is throw-away code
- nsAutoCString partial(aFilePath);
- partial.Truncate(mPattern.Length() - 1);
- nsAutoCString pattern(mPattern);
- pattern.Truncate(mPattern.Length() - 1);
- if (partial.Equals(pattern)) {
+ // Need to match using match-dest, if it exists
+ if (mMatchDest.IsEmpty() ||
+ mMatchDest.IndexOf(
+ dom::InternalRequest::MapContentPolicyTypeToRequestDestination(
+ aType)) != mMatchDest.NoIndex) {
+ // XXX remove this when we get URLPattern
+ // XXX temp: handle https://site/foo* or https://site/foo?query=*, or
+ // https://site/foo/*, etc
+ if (mPattern.Last() == '*' && aFilePath.Length() >= mPattern.Length()) {
+ // XXX not efficient, but this is throw-away code
+ nsAutoCString partial(aFilePath);
+ partial.Truncate(mPattern.Length() - 1);
+ nsAutoCString pattern(mPattern);
+ pattern.Truncate(mPattern.Length() - 1);
+ if (partial.Equals(pattern)) {
+ aLongest = mPattern.Length();
+ DICTIONARY_LOG(("Match: %s (longest %u)",
+ PromiseFlatCString(mURI).get(), aLongest));
+ return true;
+ }
+ return false;
+ // XXX handle https://site/foo/* (
+ } else if (mPattern.Equals(aFilePath)) {
+ if (mHash.IsEmpty()) {
+ return false;
+ }
aLongest = mPattern.Length();
DICTIONARY_LOG(("Match: %s (longest %u)", mURI.get(), aLongest));
return true;
}
- return false;
- // XXX handle https://site/foo/* (
- } else if (mPattern.Equals(aFilePath)) {
- if (mHash.IsEmpty()) {
- return false;
- }
- aLongest = mPattern.Length();
- DICTIONARY_LOG(
- ("Match: %s (longest %u)", PromiseFlatCString(mURI).get(), aLongest));
- return true;
}
}
return false;
@@ -284,16 +312,18 @@ void DictionaryCacheEntry::FinishHash() {
}
}
+// Version of metadata entries we expect
+static const uint32_t METADATA_VERSION = 1;
+
// Metadata format:
-// * XXX What key should these be under?
-// * uint16_t version
-// * uint16_t flags ?
+// |version|hash|pattern|[matchdest|]*||id|expiration|type
//
// * Entries:
-// ** CString: URI -- the key
+// ** CString: URI -- the key, not in the entry
+// ** CString: Version (1)
// ** CString: Hash
// ** CString: Pattern
-// ** match-dest list, terminated by empty string
+// ** match-dest CString list, terminated by empty string
// *** CString: Match-dest
// ** CString: Id
// ** CString: type
@@ -328,11 +358,14 @@ static void EscapeMetadataString(const nsACString& aInput, nsCString& aOutput) {
}
void DictionaryCacheEntry::MakeMetadataEntry(nsCString& aNewValue) {
- EscapeMetadataString(mHash, aNewValue);
+ aNewValue.AppendLiteral("|"), aNewValue.AppendInt(METADATA_VERSION),
+ EscapeMetadataString(mHash, aNewValue);
EscapeMetadataString(mPattern, aNewValue);
EscapeMetadataString(mId, aNewValue);
+ for (auto& dest : mMatchDest) {
+ EscapeMetadataString(dom::GetEnumString(dest), aNewValue);
+ }
// List of match-dest values is terminated by an empty string
- // XXX add match-dest support
EscapeMetadataString(""_ns, aNewValue);
// We don't store type, since we only support type 'raw' We can support
// type in the future by considering missing type as raw without changing the
@@ -356,6 +389,11 @@ nsresult DictionaryCacheEntry::RemoveEntry(nsICacheEntry* aCacheEntry) {
static const char* GetEncodedString(const char* aSrc, nsACString& aOutput) {
// scan the input string and build the output, handling escapes
aOutput.Truncate();
+ MOZ_ASSERT(*aSrc == '|' || *aSrc == 0);
+ if (!aSrc || *aSrc != '|') {
+ return aSrc;
+ }
+ aSrc++;
while (*aSrc) {
if (*aSrc == '|') {
break;
@@ -370,8 +408,14 @@ static const char* GetEncodedString(const char* aSrc, nsACString& aOutput) {
// Parse metadata from DictionaryOrigin
bool DictionaryCacheEntry::ParseMetadata(const char* aSrc) {
- MOZ_ASSERT(*aSrc == '|');
- aSrc++;
+ // Using mHash as a temp for version
+ aSrc = GetEncodedString(aSrc, mHash);
+ const char* tmp = mHash.get();
+ uint32_t version = atoi(tmp);
+ if (version != METADATA_VERSION) {
+ return false;
+ }
+ aSrc = GetEncodedString(aSrc, mHash);
aSrc = GetEncodedString(aSrc, mHash);
aSrc = GetEncodedString(aSrc, mPattern);
aSrc = GetEncodedString(aSrc, mId);
@@ -380,16 +424,22 @@ bool DictionaryCacheEntry::ParseMetadata(const char* aSrc) {
do {
aSrc = GetEncodedString(aSrc, temp);
if (!temp.IsEmpty()) {
- // XXX store match-dest
+ dom::RequestDestination dest =
+ dom::StringToEnum<dom::RequestDestination>(temp).valueOr(
+ dom::RequestDestination::_empty);
+ if (dest != dom::RequestDestination::_empty) {
+ mMatchDest.AppendElement(dest);
+ }
}
} while (!temp.IsEmpty());
// XXX type
aSrc = GetEncodedString(aSrc, temp);
- DICTIONARY_LOG(("Parse entry %s: |%s| %s id=%s",
- PromiseFlatCString(mURI).get(),
- PromiseFlatCString(mHash).get(),
- PromiseFlatCString(mPattern).get(), mId.get()));
+ DICTIONARY_LOG(
+ ("Parse entry %s: |%s| %s match-dest[0]=%s id=%s", mURI.get(),
+ mHash.get(), mPattern.get(),
+ mMatchDest.Length() > 0 ? dom::GetEnumString(mMatchDest[0]).get() : "",
+ mId.get()));
return true;
}
@@ -553,10 +603,11 @@ class DictionaryOriginReader final : public nsICacheEntryOpenCallback,
// a Dictionary to a maybe-existing Origin and we need to create it if it
// doesn't exist yet.
void Start(DictionaryOrigin* aOrigin, nsACString& aKey, nsIURI* aURI,
- DictionaryCache* aCache,
+ ExtContentPolicyType aType, DictionaryCache* aCache,
const std::function<nsresult(DictionaryCacheEntry*)>& aCallback) {
mOrigin = aOrigin;
mURI = aURI;
+ mType = aType;
mCallback = aCallback;
mCache = aCache;
mSelf = this; // keep this alive until we call aCallback
@@ -581,6 +632,7 @@ class DictionaryOriginReader final : public nsICacheEntryOpenCallback,
RefPtr<DictionaryOrigin> mOrigin;
nsCOMPtr<nsIURI> mURI;
+ ExtContentPolicyType mType;
std::function<nsresult(DictionaryCacheEntry*)> mCallback;
RefPtr<DictionaryCache> mCache;
RefPtr<DictionaryOriginReader> mSelf;
@@ -648,7 +700,7 @@ NS_IMETHODIMP DictionaryOriginReader::OnCacheEntryAvailable(
nsCString path;
mURI->GetPathQueryRef(path);
- RefPtr<DictionaryCacheEntry> result = origin->Match(path);
+ RefPtr<DictionaryCacheEntry> result = origin->Match(path, mType);
(mCallback)(result);
mSelf = nullptr; // this will delete 'this'
@@ -711,6 +763,7 @@ nsresult DictionaryCache::Init() {
nsresult DictionaryCache::AddEntry(nsIURI* aURI, const nsACString& aKey,
const nsACString& aPattern,
+ nsTArray<nsCString>& aMatchDest,
const nsACString& aId,
const Maybe<nsCString>& aHash,
bool aNewEntry,
@@ -719,7 +772,7 @@ nsresult DictionaryCache::AddEntry(nsIURI* aURI, const nsACString& aKey,
// has been received, we can't use it. The Hash being null is a flag
// that it's not yet valid.
RefPtr<DictionaryCacheEntry> dict =
- new DictionaryCacheEntry(aKey, aPattern, aId, aHash);
+ new DictionaryCacheEntry(aKey, aPattern, aMatchDest, aId, aHash);
dict = AddEntry(aURI, aNewEntry, dict);
if (dict) {
*aDictEntry = do_AddRef(dict).take();
@@ -754,8 +807,9 @@ already_AddRefed<DictionaryCacheEntry> DictionaryCache::AddEntry(
// Open (and parse metadata) or create
RefPtr<DictionaryOriginReader> reader = new DictionaryOriginReader();
+ // the type is irrelevant; we won't be calling Match()
reader->Start(
- origin, prepath, aURI, this,
+ origin, prepath, aURI, ExtContentPolicy::TYPE_OTHER, this,
[entry = RefPtr(aDictEntry)](
DictionaryCacheEntry*
aDict) { // XXX avoid so many lambdas which cause allocations
@@ -888,7 +942,7 @@ void DictionaryCache::RemoveAllDictionaries() {
// Once we have a DictionaryOrigin (in-memory or parsed), scan it for matches.
// If it's not in the cache, return nullptr via callback.
void DictionaryCache::GetDictionaryFor(
- nsIURI* aURI,
+ nsIURI* aURI, ExtContentPolicyType aType,
const std::function<nsresult(DictionaryCacheEntry*)>& aCallback) {
// Note: IETF 2.2.3 Multiple Matching Directories
// We need to return match-dest matches first
@@ -906,7 +960,7 @@ void DictionaryCache::GetDictionaryFor(
aURI->GetPathQueryRef(path);
DICTIONARY_LOG(("GetDictionaryFor(%s %s)", prepath.get(), path.get()));
- result = origin.Data()->Match(path);
+ result = origin.Data()->Match(path, aType);
(aCallback)(result);
return;
}
@@ -937,7 +991,7 @@ void DictionaryCache::GetDictionaryFor(
RefPtr<DictionaryOriginReader> reader = new DictionaryOriginReader();
// After Start(), if we drop this ref reader will kill itself on
// completion; it holds a self-ref
- reader->Start(nullptr, prepath, aURI, this, aCallback);
+ reader->Start(nullptr, prepath, aURI, aType, this, aCallback);
} else {
// No dictionaries for origin
(aCallback)(nullptr);
@@ -1126,12 +1180,13 @@ void DictionaryOrigin::Clear() {
}
// caller will throw this into a RefPtr
-DictionaryCacheEntry* DictionaryOrigin::Match(const nsACString& aPath) {
+DictionaryCacheEntry* DictionaryOrigin::Match(const nsACString& aPath,
+ ExtContentPolicyType aType) {
uint32_t longest = 0;
DictionaryCacheEntry* result = nullptr;
for (const auto& dict : mEntries) {
- if (dict->Match(aPath, longest)) {
+ if (dict->Match(aPath, aType, longest)) {
result = dict;
}
}
diff --git a/netwerk/cache2/Dictionary.h b/netwerk/cache2/Dictionary.h
@@ -19,6 +19,7 @@
#include "mozilla/Vector.h"
#include "nsString.h"
#include "nsTArray.h"
+#include "mozilla/dom/RequestBinding.h"
#include "mozilla/TimeStamp.h"
#include "nsTHashMap.h"
#include "nsHashKeys.h"
@@ -58,11 +59,16 @@ class DictionaryCacheEntry final : public nsICacheEntryOpenCallback,
DictionaryCacheEntry(const char* aKey);
DictionaryCacheEntry(const nsACString& aKey, const nsACString& aPattern,
- const nsACString& aId,
+ nsTArray<nsCString>& aMatchDest, const nsACString& aId,
const Maybe<nsCString>& aHash = Nothing());
+ static void ConvertMatchDestToEnumArray(
+ const nsTArray<nsCString>& aMatchDest,
+ nsTArray<dom::RequestDestination>& aMatchEnums);
+
// returns true if the pattern for the dictionary matches the path given
- bool Match(const nsACString& aFilePath, uint32_t& aLongest);
+ bool Match(const nsACString& aFilePath, ExtContentPolicyType aType,
+ uint32_t& aLongest);
// This will fail if the cache entry is no longer available.
// Start reading the cache entry into memory and call completion
@@ -168,8 +174,8 @@ class DictionaryCacheEntry final : public nsICacheEntryOpenCallback,
nsCString mURI; // URI (without ref) for the dictionary
nsCString mPattern;
nsCString mId; // max length 1024
- // XXX add list of match-dest values
- // XXX add type
+ nsTArray<dom::RequestDestination> mMatchDest;
+ // XXX add type
// dcb and dcz use type 'raw'. We're allowed to ignore types we don't
// understand, so we can fail to record a dictionary with type != 'raw'
@@ -241,7 +247,8 @@ class DictionaryOrigin : public nsICacheEntryMetaDataVisitor {
DictionaryCacheEntry* aDictEntry, bool aNewEntry);
nsresult RemoveEntry(const nsACString& aKey);
void RemoveEntry(DictionaryCacheEntry* aEntry);
- DictionaryCacheEntry* Match(const nsACString& path);
+ DictionaryCacheEntry* Match(const nsACString& path,
+ ExtContentPolicyType aType);
void FinishAddEntry(DictionaryCacheEntry* aEntry);
void Clear();
@@ -281,9 +288,9 @@ class DictionaryCache final {
nsresult Init();
nsresult AddEntry(nsIURI* aURI, const nsACString& aKey,
- const nsACString& aPattern, const nsACString& aId,
- const Maybe<nsCString>& aHash, bool aNewEntry,
- DictionaryCacheEntry** aDictEntry);
+ const nsACString& aPattern, nsTArray<nsCString>& aMatchDest,
+ const nsACString& aId, const Maybe<nsCString>& aHash,
+ bool aNewEntry, DictionaryCacheEntry** aDictEntry);
already_AddRefed<DictionaryCacheEntry> AddEntry(
nsIURI* aURI, bool aNewEntry, DictionaryCacheEntry* aDictEntry);
@@ -303,7 +310,7 @@ class DictionaryCache final {
// return an entry
void GetDictionaryFor(
- nsIURI* aURI,
+ nsIURI* aURI, ExtContentPolicyType aType,
const std::function<nsresult(DictionaryCacheEntry*)>& aCallback);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1961,8 +1961,8 @@ nsresult nsHttpChannel::SetupChannelForTransaction() {
// dictionary cache entry from disk before adding the headers. We can
// continue with channel creation, and just block on this being done later
rv = gHttpHandler->AddAcceptAndDictionaryHeaders(
- mURI, &mRequestHead, IsHTTPS(),
- [self = RefPtr(this)](DictionaryCacheEntry* aDict) {
+ mURI, mLoadInfo->GetExternalContentPolicyType(), &mRequestHead,
+ IsHTTPS(), [self = RefPtr(this)](DictionaryCacheEntry* aDict) {
self->mDictDecompress = aDict;
if (self->mDictDecompress) {
LOG_DICTIONARIES(
@@ -6016,11 +6016,13 @@ bool nsHttpChannel::ParseDictionary(nsICacheEntry* aEntry,
RefPtr<DictionaryCache> dicts(DictionaryCache::GetInstance());
LOG_DICTIONARIES(
("Adding DictionaryCache entry for %s: key %s, matchval %s, id=%s, "
- "type=%s",
+ "match-dest[0]=%s, type=%s",
mURI->GetSpecOrDefault().get(), key.get(), matchVal.get(),
- matchIdVal.get(), typeVal.get()));
- dicts->AddEntry(mURI, key, matchVal, matchIdVal, Some(hash), aModified,
- getter_AddRefs(mDictSaving));
+ matchIdVal.get(),
+ matchDestItems.Length() > 0 ? matchDestItems[0].get() : "<none>",
+ typeVal.get()));
+ dicts->AddEntry(mURI, key, matchVal, matchDestItems, matchIdVal, Some(hash),
+ aModified, getter_AddRefs(mDictSaving));
// If this was 304 Not Modified, then we don't need the dictionary data
// (though we may update the dictionary entry if the match/id/etc changed).
// If this is 304, mDictSaving will be cleared by AddEntry.
diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -655,8 +655,8 @@ nsresult nsHttpHandler::InitConnectionMgr() {
// We're using RequestOverride because this can get called when these are
// set by Fetch from the old request
nsresult nsHttpHandler::AddAcceptAndDictionaryHeaders(
- nsIURI* aURI, nsHttpRequestHead* aRequest, bool aSecure,
- const std::function<bool(DictionaryCacheEntry*)>& aCallback) {
+ nsIURI* aURI, ExtContentPolicyType aType, nsHttpRequestHead* aRequest,
+ bool aSecure, const std::function<bool(DictionaryCacheEntry*)>& aCallback) {
LOG(("Adding Dictionary headers"));
nsresult rv = NS_OK;
// Add the "Accept-Encoding" header and possibly Dictionary headers
@@ -664,8 +664,9 @@ nsresult nsHttpHandler::AddAcceptAndDictionaryHeaders(
// The dictionary info may require us to check the cache.
if (StaticPrefs::network_http_dictionaries_enable()) {
mDictionaryCache->GetDictionaryFor(
- aURI, [self = RefPtr(this), aRequest,
- aCallback](DictionaryCacheEntry* aDict) {
+ aURI, aType,
+ [self = RefPtr(this), aRequest,
+ aCallback](DictionaryCacheEntry* aDict) {
nsresult rv;
if (aDict) {
nsAutoCStringN<64> encodedHash =
diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h
@@ -118,7 +118,8 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
static already_AddRefed<nsHttpHandler> GetInstance();
[[nodiscard]] nsresult AddAcceptAndDictionaryHeaders(
- nsIURI* aURI, nsHttpRequestHead* aRequest, bool aSecure,
+ nsIURI* aURI, ExtContentPolicyType aType, nsHttpRequestHead* aRequest,
+ bool aSecure,
const std::function<bool(DictionaryCacheEntry*)>& aCallback);
[[nodiscard]] nsresult AddStandardRequestHeaders(
nsHttpRequestHead*, nsIURI* aURI, ExtContentPolicyType aContentPolicyType,