зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1407276 - Avoid creating InterceptedHttpChannel if the service worker has no fetch event handler r=dom-workers-and-storage-reviewers,asuth
Differential Revision: https://phabricator.services.mozilla.com/D64092 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
71dfe3313d
Коммит
98c35e4d3a
|
@ -21,6 +21,7 @@ struct IPCServiceWorkerDescriptor
|
|||
nsCString scope;
|
||||
nsCString scriptURL;
|
||||
ServiceWorkerState state;
|
||||
bool handlesFetch;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -29,6 +29,8 @@ ServiceWorkerDescriptor::ServiceWorkerDescriptor(
|
|||
mData->scope() = aScope;
|
||||
mData->scriptURL() = aScriptURL;
|
||||
mData->state() = aState;
|
||||
// Set HandlesFetch as true in default
|
||||
mData->handlesFetch() = true;
|
||||
}
|
||||
|
||||
ServiceWorkerDescriptor::ServiceWorkerDescriptor(
|
||||
|
@ -37,7 +39,7 @@ ServiceWorkerDescriptor::ServiceWorkerDescriptor(
|
|||
const nsACString& aScriptURL, ServiceWorkerState aState)
|
||||
: mData(MakeUnique<IPCServiceWorkerDescriptor>(
|
||||
aId, aRegistrationId, aRegistrationVersion, aPrincipalInfo,
|
||||
nsCString(aScriptURL), nsCString(aScope), aState)) {}
|
||||
nsCString(aScriptURL), nsCString(aScope), aState, true)) {}
|
||||
|
||||
ServiceWorkerDescriptor::ServiceWorkerDescriptor(
|
||||
const IPCServiceWorkerDescriptor& aDescriptor)
|
||||
|
@ -118,6 +120,14 @@ void ServiceWorkerDescriptor::SetRegistrationVersion(uint64_t aVersion) {
|
|||
mData->registrationVersion() = aVersion;
|
||||
}
|
||||
|
||||
bool ServiceWorkerDescriptor::HandlesFetch() const {
|
||||
return mData->handlesFetch();
|
||||
}
|
||||
|
||||
void ServiceWorkerDescriptor::SetHandlesFetch(bool aHandlesFetch) {
|
||||
mData->handlesFetch() = aHandlesFetch;
|
||||
}
|
||||
|
||||
bool ServiceWorkerDescriptor::Matches(
|
||||
const ServiceWorkerDescriptor& aDescriptor) const {
|
||||
return Id() == aDescriptor.Id() && Scope() == aDescriptor.Scope() &&
|
||||
|
|
|
@ -82,6 +82,10 @@ class ServiceWorkerDescriptor final {
|
|||
|
||||
void SetRegistrationVersion(uint64_t aVersion);
|
||||
|
||||
bool HandlesFetch() const;
|
||||
|
||||
void SetHandlesFetch(bool aHandlesFetch);
|
||||
|
||||
// Try to determine if two workers match each other. This is less strict
|
||||
// than an operator==() call since it ignores mutable values like State().
|
||||
bool Matches(const ServiceWorkerDescriptor& aDescriptor) const;
|
||||
|
|
|
@ -126,6 +126,7 @@ class ServiceWorkerInfo final : public nsIServiceWorkerInfo {
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(mHandlesFetch == Unknown);
|
||||
mHandlesFetch = aHandlesFetch ? Enabled : Disabled;
|
||||
mDescriptor.SetHandlesFetch(aHandlesFetch);
|
||||
}
|
||||
|
||||
void SetRegistrationVersion(uint64_t aVersion);
|
||||
|
|
|
@ -32,7 +32,14 @@ ServiceWorkerInterceptController::ShouldPrepareForIntercept(
|
|||
if (!nsContentUtils::IsNonSubresourceRequest(aChannel)) {
|
||||
const Maybe<ServiceWorkerDescriptor>& controller =
|
||||
loadInfo->GetController();
|
||||
*aShouldIntercept = controller.isSome();
|
||||
// If the controller doesn't handle fetch events, return false
|
||||
// TODO: https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm
|
||||
// 17.2. May need to schedule a soft-update.
|
||||
if (controller.isSome()) {
|
||||
*aShouldIntercept = controller.ref().HandlesFetch();
|
||||
} else {
|
||||
*aShouldIntercept = false;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -41,7 +48,7 @@ ServiceWorkerInterceptController::ShouldPrepareForIntercept(
|
|||
|
||||
// First check with the ServiceWorkerManager for a matching service worker.
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (!swm || !swm->IsAvailable(principal, aURI)) {
|
||||
if (!swm || !swm->IsAvailable(principal, aURI, aChannel)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -2313,13 +2313,59 @@ void ServiceWorkerManager::DispatchFetchEvent(nsIInterceptedChannel* aChannel,
|
|||
aRv = uploadChannel->EnsureUploadStreamIsCloneable(permissionsRunnable);
|
||||
}
|
||||
|
||||
bool ServiceWorkerManager::IsAvailable(nsIPrincipal* aPrincipal, nsIURI* aURI) {
|
||||
bool ServiceWorkerManager::IsAvailable(nsIPrincipal* aPrincipal, nsIURI* aURI,
|
||||
nsIChannel* aChannel) {
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(aURI);
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||
GetServiceWorkerRegistrationInfo(aPrincipal, aURI);
|
||||
return registration && registration->GetActive();
|
||||
|
||||
// For child interception, just check the availability.
|
||||
if (!ServiceWorkerParentInterceptEnabled()) {
|
||||
return registration && registration->GetActive();
|
||||
}
|
||||
|
||||
if (!registration || !registration->GetActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checking if the matched service worker handles fetch events or not.
|
||||
// If it does, directly return true and handle the client controlling logic
|
||||
// in DispatchFetchEvent(). otherwise, do followings then return false.
|
||||
// 1. Set the matched service worker as the controller of LoadInfo and
|
||||
// correspoinding ClinetInfo
|
||||
// 2. Maybe schedule a soft update
|
||||
if (!registration->GetActive()->HandlesFetch()) {
|
||||
// Checkin if the channel is not storage allowed first.
|
||||
if (StorageAllowedForChannel(aChannel) != StorageAccess::eAllow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ServiceWorkerInterceptController::ShouldPrepareForIntercept() handles the
|
||||
// subresource cases. Must be non-subresource case here.
|
||||
MOZ_ASSERT(nsContentUtils::IsNonSubresourceRequest(aChannel));
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
|
||||
Maybe<ClientInfo> clientInfo = loadInfo->GetReservedClientInfo();
|
||||
if (clientInfo.isNothing()) {
|
||||
clientInfo = loadInfo->GetInitialClientInfo();
|
||||
}
|
||||
|
||||
if (clientInfo.isSome()) {
|
||||
StartControllingClient(clientInfo.ref(), registration);
|
||||
}
|
||||
loadInfo->SetController(registration->GetActive()->Descriptor());
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm 17.1
|
||||
// try schedule a soft-update for non-subresource case.
|
||||
registration->MaybeScheduleTimeCheckAndUpdate();
|
||||
return false;
|
||||
}
|
||||
// Found a matching service worker which handles fetch events, return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult ServiceWorkerManager::GetClientRegistration(
|
||||
|
|
|
@ -116,7 +116,14 @@ class ServiceWorkerManager final : public nsIServiceWorkerManager,
|
|||
NS_DECL_NSISERVICEWORKERMANAGER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
bool IsAvailable(nsIPrincipal* aPrincipal, nsIURI* aURI);
|
||||
// Return true if the given principal and URI matches a registered service
|
||||
// worker which handles fetch event.
|
||||
// If there is a matched service worker but doesn't handle fetch events, this
|
||||
// method will try to set the matched service worker as the controller of the
|
||||
// passed in channel. Then also schedule a soft-update job for the service
|
||||
// worker.
|
||||
bool IsAvailable(nsIPrincipal* aPrincipal, nsIURI* aURI,
|
||||
nsIChannel* aChannel);
|
||||
|
||||
// Return true if the given content process could potentially be executing
|
||||
// service worker code with the given principal. At the current time, this
|
||||
|
|
Загрузка…
Ссылка в новой задаче