tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit bf874cae0dc56c292e7e3a5658eeb33bdce5be5e
parent 115be236bf2b8aff98f8c885dcf2ea3886f174a7
Author: Randell Jesup <rjesup@mozilla.com>
Date:   Tue,  7 Oct 2025 14:07:07 +0000

Bug 1917976: Compression Dictionary match-dest support r=necko-reviewers,valentin,kershaw

Differential Revision: https://phabricator.services.mozilla.com/D258169

Diffstat:
Mdom/fetch/InternalRequest.cpp | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdom/fetch/InternalRequest.h | 2++
Mnetwerk/cache2/CacheFileMetadata.cpp | 3++-
Mnetwerk/cache2/Dictionary.cpp | 147++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mnetwerk/cache2/Dictionary.h | 25++++++++++++++++---------
Mnetwerk/protocol/http/nsHttpChannel.cpp | 14++++++++------
Mnetwerk/protocol/http/nsHttpHandler.cpp | 9+++++----
Mnetwerk/protocol/http/nsHttpHandler.h | 3++-
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,