Skip to content

Commit

Permalink
Bug 1753730 - Add EarlyHintPreloader to load 103 Early Hint responses…
Browse files Browse the repository at this point in the history
… into the cache r=necko-reviewers,ckerschb,dragana,kershaw

Currently only same origin requests are preloaded and preloads in the
secure context. This may change in the future to match W3C decisions and
Chromes behavior.

Also only images get preloaded. This will change in the future to cover
asset types.

Currently the anchor isn't parsed correctly yet[1], so this will be
fixed in a future patch.

On non-2xx responses of the main document all ongoing preloads get
canceled. Already completed preloads don't get affected and are in the
cache.

It is currently untested whether unused preloads don't have side effects.

Another future patch should cover adding the preload to the devtools.

[1]: https://datatracker.ietf.org/doc/html/rfc8288#section-3.2

Differential Revision: https://phabricator.services.mozilla.com/D137885
  • Loading branch information
mb committed May 11, 2022
1 parent 318581f commit b01d289
Show file tree
Hide file tree
Showing 10 changed files with 502 additions and 16 deletions.
4 changes: 4 additions & 0 deletions docshell/base/CanonicalBrowsingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,10 @@ void CanonicalBrowsingContext::AddFinalDiscardListener(
mFullyDiscardedListeners.AppendElement(std::move(aListener));
}

net::EarlyHintsService* CanonicalBrowsingContext::GetEarlyHintsService() {
return &mEarlyHintsService;
}

void CanonicalBrowsingContext::AdjustPrivateBrowsingCount(
bool aPrivateBrowsing) {
if (IsDiscarded() || !EverAttached() || IsChrome()) {
Expand Down
5 changes: 5 additions & 0 deletions docshell/base/CanonicalBrowsingContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef mozilla_dom_CanonicalBrowsingContext_h
#define mozilla_dom_CanonicalBrowsingContext_h

#include "mozilla/net/EarlyHintsService.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/MediaControlKeySource.h"
#include "mozilla/dom/BrowsingContextWebProgress.h"
Expand Down Expand Up @@ -361,6 +362,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {

void AddFinalDiscardListener(std::function<void(uint64_t)>&& aListener);

net::EarlyHintsService* GetEarlyHintsService();

protected:
// Called when the browsing context is being discarded.
void CanonicalDiscard();
Expand Down Expand Up @@ -564,6 +567,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {
bool mFullyDiscarded = false;

nsTArray<std::function<void(uint64_t)>> mFullyDiscardedListeners;

net::EarlyHintsService mEarlyHintsService;
};

} // namespace dom
Expand Down
6 changes: 6 additions & 0 deletions modules/libpref/init/StaticPrefList.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10353,6 +10353,12 @@
value: true
mirror: always

# Enable 103 Early Hint status code (RFC 8297)
- name: network.early-hints.enabled
type: RelaxedAtomicBool
value: false
mirror: always

# Whether to use the network process or not
# Start a separate socket process. Performing networking on the socket process
# is control by a sepparate pref
Expand Down
26 changes: 17 additions & 9 deletions netwerk/ipc/DocumentLoadListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1104,7 +1104,9 @@ void DocumentLoadListener::Disconnect(bool aContinueNavigating) {
httpChannelImpl->SetEarlyHintObserver(nullptr);
}

mEarlyHintsService.Cancel();
if (GetLoadingBrowsingContext()) {
GetLoadingBrowsingContext()->mEarlyHintsService.Cancel();
}

if (auto* ctx = GetDocumentBrowsingContext()) {
ctx->EndDocumentLoad(aContinueNavigating);
Expand Down Expand Up @@ -2472,12 +2474,15 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
}
}

if (httpChannel) {
uint32_t responseStatus;
Unused << httpChannel->GetResponseStatus(&responseStatus);
mEarlyHintsService.FinalResponse(responseStatus);
} else {
mEarlyHintsService.Cancel();
if (GetLoadingBrowsingContext()) {
if (httpChannel) {
uint32_t responseStatus;
Unused << httpChannel->GetResponseStatus(&responseStatus);
GetLoadingBrowsingContext()->mEarlyHintsService.FinalResponse(
responseStatus);
} else {
GetLoadingBrowsingContext()->mEarlyHintsService.Cancel();
}
}

// If we're going to be delivering this channel to a remote content
Expand Down Expand Up @@ -2848,8 +2853,11 @@ NS_IMETHODIMP DocumentLoadListener::OnStatus(nsIRequest* aRequest,

NS_IMETHODIMP DocumentLoadListener::EarlyHint(const nsACString& linkHeader) {
LOG(("DocumentLoadListener::EarlyHint.\n"));

mEarlyHintsService.EarlyHint(linkHeader);
if (GetLoadingBrowsingContext()) {
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
GetLoadingBrowsingContext()->mEarlyHintsService.EarlyHint(
linkHeader, GetChannelCreationURI(), loadInfo);
}
return NS_OK;
}

Expand Down
2 changes: 0 additions & 2 deletions netwerk/ipc/DocumentLoadListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -619,8 +619,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
bool mOpenPromiseResolved = false;

const bool mIsDocumentLoad;

EarlyHintsService mEarlyHintsService;
};

NS_DEFINE_STATIC_IID_ACCESSOR(DocumentLoadListener, DOCUMENT_LOAD_LISTENER_IID)
Expand Down
Loading

0 comments on commit b01d289

Please sign in to comment.