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.
|
// This should only happen if IsAvailable() returned true.
|
||||||
MOZ_ASSERT(registration->mActiveWorker);
|
MOZ_ASSERT(registration->mActiveWorker);
|
||||||
serviceWorker = registration->mActiveWorker;
|
serviceWorker = registration->mActiveWorker;
|
||||||
|
|
||||||
|
AddNavigationInterception(serviceWorker->Scope(), aChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(aRv.Failed()) || !serviceWorker) {
|
if (NS_WARN_IF(aRv.Failed()) || !serviceWorker) {
|
||||||
@ -4190,6 +4192,76 @@ ServiceWorkerManager::AddRegisteringDocument(const nsACString& aScope,
|
|||||||
list->AppendElement(do_GetWeakReference(aDoc));
|
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_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -328,6 +328,18 @@ public:
|
|||||||
typedef nsTArray<nsCOMPtr<nsIWeakReference>> WeakDocumentList;
|
typedef nsTArray<nsCOMPtr<nsIWeakReference>> WeakDocumentList;
|
||||||
nsClassHashtable<nsCStringHashKey, WeakDocumentList> mRegisteringDocuments;
|
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
|
bool
|
||||||
IsAvailable(const OriginAttributes& aOriginAttributes, nsIURI* aURI);
|
IsAvailable(const OriginAttributes& aOriginAttributes, nsIURI* aURI);
|
||||||
|
|
||||||
@ -622,6 +634,16 @@ private:
|
|||||||
|
|
||||||
void
|
void
|
||||||
AddRegisteringDocument(const nsACString& aScope, nsIDocument* aDoc);
|
AddRegisteringDocument(const nsACString& aScope, nsIDocument* aDoc);
|
||||||
|
|
||||||
|
class InterceptionReleaseHandle;
|
||||||
|
|
||||||
|
void
|
||||||
|
AddNavigationInterception(const nsACString& aScope,
|
||||||
|
nsIInterceptedChannel* aChannel);
|
||||||
|
|
||||||
|
void
|
||||||
|
RemoveNavigationInterception(const nsACString& aScope,
|
||||||
|
nsIInterceptedChannel* aChannel);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace workers
|
} // namespace workers
|
||||||
|
@ -56,6 +56,7 @@ InterceptedJARChannel::ResetInterception()
|
|||||||
mSynthesizedInput = nullptr;
|
mSynthesizedInput = nullptr;
|
||||||
|
|
||||||
mChannel->ResetInterception();
|
mChannel->ResetInterception();
|
||||||
|
mReleaseHandle = nullptr;
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -93,6 +94,7 @@ InterceptedJARChannel::FinishSynthesizedResponse(const nsACString& aFinalURLSpec
|
|||||||
mChannel->OverrideWithSynthesizedResponse(mSynthesizedInput, mContentType);
|
mChannel->OverrideWithSynthesizedResponse(mSynthesizedInput, mContentType);
|
||||||
|
|
||||||
mResponseBody = nullptr;
|
mResponseBody = nullptr;
|
||||||
|
mReleaseHandle = nullptr;
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -109,6 +111,7 @@ InterceptedJARChannel::Cancel(nsresult aStatus)
|
|||||||
nsresult rv = mChannel->Cancel(aStatus);
|
nsresult rv = mChannel->Cancel(aStatus);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
mResponseBody = nullptr;
|
mResponseBody = nullptr;
|
||||||
|
mReleaseHandle = nullptr;
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -129,6 +132,16 @@ InterceptedJARChannel::GetConsoleReportCollector(nsIConsoleReportCollector**)
|
|||||||
return NS_ERROR_NOT_AVAILABLE;
|
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
|
void
|
||||||
InterceptedJARChannel::NotifyController()
|
InterceptedJARChannel::NotifyController()
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,8 @@ class InterceptedJARChannel : public nsIInterceptedChannel
|
|||||||
// The stream to write the body of the synthesized response.
|
// The stream to write the body of the synthesized response.
|
||||||
nsCOMPtr<nsIOutputStream> mResponseBody;
|
nsCOMPtr<nsIOutputStream> mResponseBody;
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> mReleaseHandle;
|
||||||
|
|
||||||
// The content type of the synthesized response.
|
// The content type of the synthesized response.
|
||||||
nsCString mContentType;
|
nsCString mContentType;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class ChannelInfo;
|
|||||||
* which do not implement nsIChannel.
|
* which do not implement nsIChannel.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[scriptable, uuid(231bb567-90e1-4973-9728-7dab93ab29a8)]
|
[scriptable, uuid(64439e24-eda5-4f39-9a7e-162c4b5e0150)]
|
||||||
interface nsIInterceptedChannel : nsISupports
|
interface nsIInterceptedChannel : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -100,6 +100,14 @@ interface nsIInterceptedChannel : nsISupports
|
|||||||
return reporter.forget();
|
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;
|
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,
|
InterceptedChannelChrome::InterceptedChannelChrome(nsHttpChannel* aChannel,
|
||||||
nsINetworkInterceptController* aController,
|
nsINetworkInterceptController* aController,
|
||||||
nsICacheEntry* aEntry)
|
nsICacheEntry* aEntry)
|
||||||
@ -172,6 +182,7 @@ InterceptedChannelChrome::ResetInterception()
|
|||||||
nsresult rv = mChannel->StartRedirectChannelToURI(uri, nsIChannelEventSink::REDIRECT_INTERNAL);
|
nsresult rv = mChannel->StartRedirectChannelToURI(uri, nsIChannelEventSink::REDIRECT_INTERNAL);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
mReleaseHandle = nullptr;
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -265,6 +276,7 @@ InterceptedChannelChrome::FinishSynthesizedResponse(const nsACString& aFinalURLS
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mReleaseHandle = nullptr;
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -284,6 +296,7 @@ InterceptedChannelChrome::Cancel(nsresult aStatus)
|
|||||||
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
||||||
nsresult rv = mChannel->AsyncAbort(aStatus);
|
nsresult rv = mChannel->AsyncAbort(aStatus);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
mReleaseHandle = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,6 +362,7 @@ InterceptedChannelContent::ResetInterception()
|
|||||||
mSynthesizedInput = nullptr;
|
mSynthesizedInput = nullptr;
|
||||||
|
|
||||||
mChannel->ResetInterception();
|
mChannel->ResetInterception();
|
||||||
|
mReleaseHandle = nullptr;
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -407,6 +421,7 @@ InterceptedChannelContent::FinishSynthesizedResponse(const nsACString& aFinalURL
|
|||||||
}
|
}
|
||||||
|
|
||||||
mResponseBody = nullptr;
|
mResponseBody = nullptr;
|
||||||
|
mReleaseHandle = nullptr;
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
mStreamListener = nullptr;
|
mStreamListener = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -427,6 +442,7 @@ InterceptedChannelContent::Cancel(nsresult aStatus)
|
|||||||
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
||||||
nsresult rv = mChannel->AsyncAbort(aStatus);
|
nsresult rv = mChannel->AsyncAbort(aStatus);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
mReleaseHandle = nullptr;
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
mStreamListener = nullptr;
|
mStreamListener = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -37,6 +37,7 @@ protected:
|
|||||||
Maybe<nsAutoPtr<nsHttpResponseHead>> mSynthesizedResponseHead;
|
Maybe<nsAutoPtr<nsHttpResponseHead>> mSynthesizedResponseHead;
|
||||||
|
|
||||||
nsCOMPtr<nsIConsoleReportCollector> mReportCollector;
|
nsCOMPtr<nsIConsoleReportCollector> mReportCollector;
|
||||||
|
nsCOMPtr<nsISupports> mReleaseHandle;
|
||||||
|
|
||||||
void EnsureSynthesizedResponse();
|
void EnsureSynthesizedResponse();
|
||||||
void DoNotifyController();
|
void DoNotifyController();
|
||||||
@ -55,6 +56,7 @@ public:
|
|||||||
|
|
||||||
NS_IMETHOD GetResponseBody(nsIOutputStream** aOutput) override;
|
NS_IMETHOD GetResponseBody(nsIOutputStream** aOutput) override;
|
||||||
NS_IMETHOD GetConsoleReportCollector(nsIConsoleReportCollector** aCollectorOut) override;
|
NS_IMETHOD GetConsoleReportCollector(nsIConsoleReportCollector** aCollectorOut) override;
|
||||||
|
NS_IMETHOD SetReleaseHandle(nsISupports* aHandle) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterceptedChannelChrome : public InterceptedChannelBase
|
class InterceptedChannelChrome : public InterceptedChannelBase
|
||||||
|
Loading…
Reference in New Issue
Block a user