commit df63d60f8fea02540dc294965bc7d7c5b2d84251
parent 46c6d977d7012c66a40ff5391faa0a2b302e399d
Author: Randell Jesup <rjesup@mozilla.com>
Date: Tue, 7 Oct 2025 14:07:10 +0000
Bug 1917974: Move CompressionDictionaries AddAcceptAndDictionaryHeaders to run earlier r=necko-reviewers,kershaw,devtools-reviewers,bomsy
We need to do this before we save the headers in the CacheEntry
Differential Revision: https://phabricator.services.mozilla.com/D265361
Diffstat:
4 files changed, 68 insertions(+), 52 deletions(-)
diff --git a/devtools/client/netmonitor/test/browser_net_copy_as_powershell.js b/devtools/client/netmonitor/test/browser_net_copy_as_powershell.js
@@ -19,11 +19,11 @@ add_task(async function () {
-Headers @{
"Accept" = "*/*"
"Accept-Language" = "en-US"
- "Accept-Encoding" = "gzip, deflate, br, zstd"
"X-Custom-Header-1" = "Custom value"
"X-Custom-Header-2" = "8.8.8.8"
"X-Custom-Header-3" = "Mon, 3 Mar 2014 11:11:11 GMT"
"Referer" = "https://example.com/browser/devtools/client/netmonitor/test/html_copy-as-curl.html"
+ "Accept-Encoding" = "gzip, deflate, br, zstd"
"Sec-Fetch-Dest" = "empty"
"Sec-Fetch-Mode" = "cors"
"Sec-Fetch-Site" = "same-origin"
@@ -42,11 +42,11 @@ Invoke-WebRequest -UseBasicParsing -Uri "https://example.com/browser/devtools/cl
-Headers @{
"Accept" = "*/*"
"Accept-Language" = "en-US"
- "Accept-Encoding" = "gzip, deflate, br, zstd"
"X-Custom-Header-1" = "Custom value"
"X-Custom-Header-2" = "8.8.8.8"
"X-Custom-Header-3" = "Mon, 3 Mar 2014 11:11:11 GMT"
"Referer" = "https://example.com/browser/devtools/client/netmonitor/test/html_copy-as-curl.html"
+ "Accept-Encoding" = "gzip, deflate, br, zstd"
"Sec-Fetch-Dest" = "empty"
"Sec-Fetch-Mode" = "cors"
"Sec-Fetch-Site" = "same-origin"
@@ -68,12 +68,12 @@ Invoke-WebRequest -UseBasicParsing -Uri "https://example.com/browser/devtools/cl
-Headers @{
"Accept" = "*/*"
"Accept-Language" = "en-US"
- "Accept-Encoding" = "gzip, deflate, br, zstd"
"X-Custom-Header-1" = "Custom value"
"X-Custom-Header-2" = "8.8.8.8"
"X-Custom-Header-3" = "Mon, 3 Mar 2014 11:11:11 GMT"
"Origin" = "https://example.com"
"Referer" = "https://example.com/browser/devtools/client/netmonitor/test/html_copy-as-curl.html"
+ "Accept-Encoding" = "gzip, deflate, br, zstd"
"Sec-Fetch-Dest" = "empty"
"Sec-Fetch-Mode" = "cors"
"Sec-Fetch-Site" = "same-origin"
@@ -97,12 +97,12 @@ Invoke-WebRequest -UseBasicParsing -Uri "https://example.com/browser/devtools/cl
-Headers @{
"Accept" = "*/*"
"Accept-Language" = "en-US"
- "Accept-Encoding" = "gzip, deflate, br, zstd"
"X-Custom-Header-1" = "Custom value"
"X-Custom-Header-2" = "8.8.8.8"
"X-Custom-Header-3" = "Mon, 3 Mar 2014 11:11:11 GMT"
"Origin" = "https://example.com"
"Referer" = "https://example.com/browser/devtools/client/netmonitor/test/html_copy-as-curl.html"
+ "Accept-Encoding" = "gzip, deflate, br, zstd"
"Sec-Fetch-Dest" = "empty"
"Sec-Fetch-Mode" = "cors"
"Sec-Fetch-Site" = "same-origin"
diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -543,9 +543,9 @@ void nsHttpChannel::ReleaseMainThreadOnlyReferences() {
nsresult nsHttpChannel::Init(nsIURI* uri, uint32_t caps, nsProxyInfo* proxyInfo,
uint32_t proxyResolveFlags, nsIURI* proxyURI,
uint64_t channelId, nsILoadInfo* aLoadInfo) {
+ LOG1(("nsHttpChannel::Init [this=%p]\n", this));
nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo, proxyResolveFlags,
proxyURI, channelId, aLoadInfo);
- LOG1(("nsHttpChannel::Init [this=%p]\n", this));
return rv;
}
@@ -630,6 +630,64 @@ bool nsHttpChannel::StorageAccessReloadedChannel() {
nsresult nsHttpChannel::PrepareToConnect() {
LOG(("nsHttpChannel::PrepareToConnect [this=%p]\n", this));
+ // This may be async; the dictionary headers may need to fetch an origin
+ // dictionary cache entry from disk before adding the headers. We can
+ // continue with channel creation, and just block on this being done later
+ bool async;
+ AUTO_PROFILER_FLOW_MARKER("nsHttpHandler::AddAcceptAndDictionaryHeaders",
+ NETWORK, Flow::FromPointer(this));
+ nsresult rv = gHttpHandler->AddAcceptAndDictionaryHeaders(
+ mURI, mLoadInfo->GetExternalContentPolicyType(), &mRequestHead, IsHTTPS(),
+ async,
+ [self = RefPtr(this)](bool aNeedsResume, DictionaryCacheEntry* aDict) {
+ self->mDictDecompress = aDict;
+ if (aNeedsResume) {
+ LOG_DICTIONARIES(("Resuming after getting Dictionary headers"));
+ self->Resume();
+ }
+ if (self->mDictDecompress) {
+ LOG_DICTIONARIES(
+ ("Added dictionary header for %p, DirectoryCacheEntry %p",
+ self.get(), aDict));
+ AUTO_PROFILER_FLOW_MARKER(
+ "nsHttpHandler::AddAcceptAndDictionaryHeaders Add "
+ "Available-Dictionary",
+ NETWORK, Flow::FromPointer(self));
+ // mDictDecompress is set if we added Available-Dictionary
+ self->mDictDecompress->InUse();
+ self->mUsingDictionary = true;
+ PROFILER_MARKER("Dictionary Prefetch", NETWORK,
+ MarkerTiming::IntervalStart(), FlowMarker,
+ Flow::FromPointer(self));
+ return NS_SUCCEEDED(self->mDictDecompress->Prefetch(
+ GetLoadContextInfo(self), self->mShouldSuspendForDictionary,
+ [self]() {
+ // this is called when the prefetch is complete to
+ // un-Suspend the channel
+ MOZ_ASSERT(self->mDictDecompress->DictionaryReady());
+ if (self->mSuspendedForDictionary) {
+ LOG(
+ ("nsHttpChannel::SetupChannelForTransaction [this=%p] "
+ "Resuming channel "
+ "suspended for Dictionary",
+ self.get()));
+ self->mSuspendedForDictionary = false;
+ self->Resume();
+ }
+ PROFILER_MARKER("Dictionary Prefetch", NETWORK,
+ MarkerTiming::IntervalEnd(), FlowMarker,
+ Flow::FromPointer(self));
+ }));
+ }
+ return true;
+ });
+ if (NS_FAILED(rv)) return rv;
+ if (async) {
+ // we'll continue later if GetDictionaryFor is still reading
+ LOG_DICTIONARIES(("Suspending to get Dictionary headers"));
+ Suspend();
+ }
+
// notify "http-on-modify-request-before-cookies" observers
gHttpHandler->OnModifyRequestBeforeCookies(this);
@@ -1959,52 +2017,6 @@ nsresult nsHttpChannel::SetupChannelForTransaction() {
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
}
- } else {
- // This may be async; the dictionary headers may need to fetch an origin
- // dictionary cache entry from disk before adding the headers. We can
- // continue with channel creation, and just block on this being done later
- bool async;
- rv = gHttpHandler->AddAcceptAndDictionaryHeaders(
- mURI, mLoadInfo->GetExternalContentPolicyType(), &mRequestHead,
- IsHTTPS(), async,
- [self = RefPtr(this)](bool aNeedsResume, DictionaryCacheEntry* aDict) {
- self->mDictDecompress = aDict;
- if (aNeedsResume) {
- LOG_DICTIONARIES(("Resuming after getting Dictionary headers"));
- self->Resume();
- }
- if (self->mDictDecompress) {
- LOG_DICTIONARIES(
- ("Added dictionary header for %p, DirectoryCacheEntry %p",
- self.get(), aDict));
- // mDictDecompress is set if we added Available-Dictionary
- self->mDictDecompress->InUse();
- self->mUsingDictionary = true;
- return NS_SUCCEEDED(self->mDictDecompress->Prefetch(
- GetLoadContextInfo(self), self->mShouldSuspendForDictionary,
- [self]() {
- // this is called when the prefetch is complete to
- // un-Suspend the channel
- MOZ_ASSERT(self->mDictDecompress->DictionaryReady());
- if (self->mSuspendedForDictionary) {
- LOG(
- ("nsHttpChannel::SetupChannelForTransaction [this=%p] "
- "Resuming channel "
- "suspended for Dictionary",
- self.get()));
- self->mSuspendedForDictionary = false;
- self->Resume();
- }
- }));
- }
- return true;
- });
- if (NS_FAILED(rv)) return rv;
- if (async) {
- // we'll continue later if GetDictionaryFor is still reading
- LOG_DICTIONARIES(("Suspending to get Dictionary headers"));
- Suspend();
- }
}
// See bug #466080. Transfer LOAD_ANONYMOUS flag to socket-layer.
diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
@@ -735,7 +735,7 @@ class nsHttpChannel final : public HttpBaseChannel,
MOZ_ATOMIC_BITFIELDS(mAtomicBitfields6, 32, (
// True if network request gets to OnStart before we get a response from the cache
(uint32_t, NetworkWonRace, 1),
- // Valid values are CachedContentValid
+ // Valid values are CachedContentValidity::Unset/Invalid/Valid
(uint32_t, CachedContentIsValid, 2),
// Only set to true when we receive an HTTPSSVC record before the
// transaction is created.
diff --git a/toolkit/components/extensions/test/mochitest/head_webrequest.js b/toolkit/components/extensions/test/mochitest/head_webrequest.js
@@ -139,12 +139,16 @@ function background(events) {
);
let deletedAny = false;
+ dump(`*** headers = ${JSON.stringify(headers)}\n`);
for (let j = headers.length; j-- > 0; ) {
if (remove.includes(headers[j].name.toLowerCase())) {
headers.splice(j, 1);
deletedAny = true;
}
}
+ dump(
+ `*** headers(after) = ${JSON.stringify(headers)}, deletedAny=${deletedAny}\n`
+ );
browser.test.assertTrue(
deletedAny,
`at least one ${phase}Headers element to delete`