mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1217909 P8 Track navigation interceptions per scope in ServiceWorkerManager. r=catalinb
This commit is contained in:
parent
f58ce91280
commit
74ebcbe8e0
@ -3240,6 +3240,8 @@ ServiceWorkerManager::PrepareFetchEvent(const OriginAttributes& aOriginAttribute
|
||||
// This should only happen if IsAvailable() returned true.
|
||||
MOZ_ASSERT(registration->mActiveWorker);
|
||||
serviceWorker = registration->mActiveWorker;
|
||||
|
||||
AddNavigationInterception(serviceWorker->Scope(), aChannel);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed()) || !serviceWorker) {
|
||||
@ -4190,6 +4192,76 @@ ServiceWorkerManager::AddRegisteringDocument(const nsACString& aScope,
|
||||
list->AppendElement(do_GetWeakReference(aDoc));
|
||||
}
|
||||
|
||||
class ServiceWorkerManager::InterceptionReleaseHandle final : public nsISupports
|
||||
{
|
||||
const nsCString mScope;
|
||||
|
||||
// Weak reference to channel is safe, because the channel holds a
|
||||
// reference to this object. Also, the pointer is only used for
|
||||
// comparison purposes.
|
||||
nsIInterceptedChannel* mChannel;
|
||||
|
||||
~InterceptionReleaseHandle()
|
||||
{
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
swm->RemoveNavigationInterception(mScope, mChannel);
|
||||
}
|
||||
|
||||
public:
|
||||
InterceptionReleaseHandle(const nsACString& aScope,
|
||||
nsIInterceptedChannel* aChannel)
|
||||
: mScope(aScope)
|
||||
, mChannel(aChannel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!aScope.IsEmpty());
|
||||
MOZ_ASSERT(mChannel);
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS0(ServiceWorkerManager::InterceptionReleaseHandle);
|
||||
|
||||
void
|
||||
ServiceWorkerManager::AddNavigationInterception(const nsACString& aScope,
|
||||
nsIInterceptedChannel* aChannel)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(!aScope.IsEmpty());
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
InterceptionList* list =
|
||||
mNavigationInterceptions.LookupOrAdd(aScope);
|
||||
MOZ_ASSERT(list);
|
||||
MOZ_ASSERT(!list->Contains(aChannel));
|
||||
|
||||
nsCOMPtr<nsISupports> releaseHandle =
|
||||
new InterceptionReleaseHandle(aScope, aChannel);
|
||||
aChannel->SetReleaseHandle(releaseHandle);
|
||||
|
||||
list->AppendElement(aChannel);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::RemoveNavigationInterception(const nsACString& aScope,
|
||||
nsIInterceptedChannel* aChannel)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aChannel);
|
||||
InterceptionList* list =
|
||||
mNavigationInterceptions.Get(aScope);
|
||||
if (list) {
|
||||
MOZ_ALWAYS_TRUE(list->RemoveElement(aChannel));
|
||||
MOZ_ASSERT(!list->Contains(aChannel));
|
||||
if (list->IsEmpty()) {
|
||||
list = nullptr;
|
||||
nsAutoPtr<InterceptionList> doomed;
|
||||
mNavigationInterceptions.RemoveAndForget(aScope, doomed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -328,6 +328,18 @@ public:
|
||||
typedef nsTArray<nsCOMPtr<nsIWeakReference>> WeakDocumentList;
|
||||
nsClassHashtable<nsCStringHashKey, WeakDocumentList> mRegisteringDocuments;
|
||||
|
||||
// Track all intercepted navigation channels for a given scope. Channels are
|
||||
// placed in the appropriate list before dispatch the FetchEvent to the worker
|
||||
// thread and removed once FetchEvent processing dispatches back to the main
|
||||
// thread.
|
||||
//
|
||||
// Note: Its safe to use weak references here because a RAII-style callback
|
||||
// is registered with the channel before its added to this list. We
|
||||
// are guaranteed the callback will fire before and remove the ref
|
||||
// from this list before the channel is destroyed.
|
||||
typedef nsTArray<nsIInterceptedChannel*> InterceptionList;
|
||||
nsClassHashtable<nsCStringHashKey, InterceptionList> mNavigationInterceptions;
|
||||
|
||||
bool
|
||||
IsAvailable(const OriginAttributes& aOriginAttributes, nsIURI* aURI);
|
||||
|
||||
@ -622,6 +634,16 @@ private:
|
||||
|
||||
void
|
||||
AddRegisteringDocument(const nsACString& aScope, nsIDocument* aDoc);
|
||||
|
||||
class InterceptionReleaseHandle;
|
||||
|
||||
void
|
||||
AddNavigationInterception(const nsACString& aScope,
|
||||
nsIInterceptedChannel* aChannel);
|
||||
|
||||
void
|
||||
RemoveNavigationInterception(const nsACString& aScope,
|
||||
nsIInterceptedChannel* aChannel);
|
||||
};
|
||||
|
||||
} // namespace workers
|
||||
|
@ -56,6 +56,7 @@ InterceptedJARChannel::ResetInterception()
|
||||
mSynthesizedInput = nullptr;
|
||||
|
||||
mChannel->ResetInterception();
|
||||
mReleaseHandle = nullptr;
|
||||
mChannel = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -93,6 +94,7 @@ InterceptedJARChannel::FinishSynthesizedResponse(const nsACString& aFinalURLSpec
|
||||
mChannel->OverrideWithSynthesizedResponse(mSynthesizedInput, mContentType);
|
||||
|
||||
mResponseBody = nullptr;
|
||||
mReleaseHandle = nullptr;
|
||||
mChannel = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -109,6 +111,7 @@ InterceptedJARChannel::Cancel(nsresult aStatus)
|
||||
nsresult rv = mChannel->Cancel(aStatus);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mResponseBody = nullptr;
|
||||
mReleaseHandle = nullptr;
|
||||
mChannel = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -129,6 +132,16 @@ InterceptedJARChannel::GetConsoleReportCollector(nsIConsoleReportCollector**)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedJARChannel::SetReleaseHandle(nsISupports* aHandle)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mReleaseHandle);
|
||||
MOZ_ASSERT(aHandle);
|
||||
mReleaseHandle = aHandle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
InterceptedJARChannel::NotifyController()
|
||||
{
|
||||
|
@ -41,6 +41,8 @@ class InterceptedJARChannel : public nsIInterceptedChannel
|
||||
// The stream to write the body of the synthesized response.
|
||||
nsCOMPtr<nsIOutputStream> mResponseBody;
|
||||
|
||||
nsCOMPtr<nsISupports> mReleaseHandle;
|
||||
|
||||
// The content type of the synthesized response.
|
||||
nsCString mContentType;
|
||||
|
||||
|
@ -29,7 +29,7 @@ class ChannelInfo;
|
||||
* which do not implement nsIChannel.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(231bb567-90e1-4973-9728-7dab93ab29a8)]
|
||||
[scriptable, uuid(64439e24-eda5-4f39-9a7e-162c4b5e0150)]
|
||||
interface nsIInterceptedChannel : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -100,6 +100,14 @@ interface nsIInterceptedChannel : nsISupports
|
||||
return reporter.forget();
|
||||
}
|
||||
%}
|
||||
|
||||
/**
|
||||
* Allow the ServiceWorkerManager to set an RAII-style object on the
|
||||
* intercepted channel that should be released once the channel is
|
||||
* torn down.
|
||||
*/
|
||||
[noscript]
|
||||
void setReleaseHandle(in nsISupports aHandle);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -118,6 +118,16 @@ InterceptedChannelBase::GetConsoleReportCollector(nsIConsoleReportCollector** aC
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedChannelBase::SetReleaseHandle(nsISupports* aHandle)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mReleaseHandle);
|
||||
MOZ_ASSERT(aHandle);
|
||||
mReleaseHandle = aHandle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
InterceptedChannelChrome::InterceptedChannelChrome(nsHttpChannel* aChannel,
|
||||
nsINetworkInterceptController* aController,
|
||||
nsICacheEntry* aEntry)
|
||||
@ -172,6 +182,7 @@ InterceptedChannelChrome::ResetInterception()
|
||||
nsresult rv = mChannel->StartRedirectChannelToURI(uri, nsIChannelEventSink::REDIRECT_INTERNAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mReleaseHandle = nullptr;
|
||||
mChannel = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -265,6 +276,7 @@ InterceptedChannelChrome::FinishSynthesizedResponse(const nsACString& aFinalURLS
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
mReleaseHandle = nullptr;
|
||||
mChannel = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -284,6 +296,7 @@ InterceptedChannelChrome::Cancel(nsresult aStatus)
|
||||
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
||||
nsresult rv = mChannel->AsyncAbort(aStatus);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mReleaseHandle = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -349,6 +362,7 @@ InterceptedChannelContent::ResetInterception()
|
||||
mSynthesizedInput = nullptr;
|
||||
|
||||
mChannel->ResetInterception();
|
||||
mReleaseHandle = nullptr;
|
||||
mChannel = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -407,6 +421,7 @@ InterceptedChannelContent::FinishSynthesizedResponse(const nsACString& aFinalURL
|
||||
}
|
||||
|
||||
mResponseBody = nullptr;
|
||||
mReleaseHandle = nullptr;
|
||||
mChannel = nullptr;
|
||||
mStreamListener = nullptr;
|
||||
return NS_OK;
|
||||
@ -427,6 +442,7 @@ InterceptedChannelContent::Cancel(nsresult aStatus)
|
||||
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
||||
nsresult rv = mChannel->AsyncAbort(aStatus);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mReleaseHandle = nullptr;
|
||||
mChannel = nullptr;
|
||||
mStreamListener = nullptr;
|
||||
return NS_OK;
|
||||
|
@ -37,6 +37,7 @@ protected:
|
||||
Maybe<nsAutoPtr<nsHttpResponseHead>> mSynthesizedResponseHead;
|
||||
|
||||
nsCOMPtr<nsIConsoleReportCollector> mReportCollector;
|
||||
nsCOMPtr<nsISupports> mReleaseHandle;
|
||||
|
||||
void EnsureSynthesizedResponse();
|
||||
void DoNotifyController();
|
||||
@ -55,6 +56,7 @@ public:
|
||||
|
||||
NS_IMETHOD GetResponseBody(nsIOutputStream** aOutput) override;
|
||||
NS_IMETHOD GetConsoleReportCollector(nsIConsoleReportCollector** aCollectorOut) override;
|
||||
NS_IMETHOD SetReleaseHandle(nsISupports* aHandle) override;
|
||||
};
|
||||
|
||||
class InterceptedChannelChrome : public InterceptedChannelBase
|
||||
|
Loading…
Reference in New Issue
Block a user