зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1725567
- P5 Support canceling fetching which launched by FetchService. r=dom-worker-reviewers,jesup
Cancel the navigation preload fetching while the FetchEvent has already received Recvdelete or RecvRespondWith Depends on D129809 Differential Revision: https://phabricator.services.mozilla.com/D130183
This commit is contained in:
Родитель
03fdb1e266
Коммит
02e83cbd20
|
@ -99,7 +99,7 @@ RefPtr<FetchServiceResponsePromise> FetchService::FetchInstance::Fetch() {
|
|||
nsresult rv;
|
||||
|
||||
// Create a FetchDriver instance
|
||||
RefPtr<FetchDriver> fetch = MakeRefPtr<FetchDriver>(
|
||||
mFetchDriver = MakeRefPtr<FetchDriver>(
|
||||
mRequest.clonePtr(), // Fetch Request
|
||||
mPrincipal, // Principal
|
||||
mLoadGroup, // LoadGroup
|
||||
|
@ -114,7 +114,7 @@ RefPtr<FetchServiceResponsePromise> FetchService::FetchInstance::Fetch() {
|
|||
// with FetchService. AbortSignalImpl related information should be passed
|
||||
// through PFetch or InterceptedHttpChannel, then call
|
||||
// FetchService::CancelFetch() to abort the running fetch.
|
||||
rv = fetch->Fetch(nullptr, this);
|
||||
rv = mFetchDriver->Fetch(nullptr, this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return FetchServiceResponsePromise::CreateAndResolve(
|
||||
InternalResponse::NetworkError(rv), __func__);
|
||||
|
@ -123,6 +123,15 @@ RefPtr<FetchServiceResponsePromise> FetchService::FetchInstance::Fetch() {
|
|||
return mResponsePromiseHolder.Ensure(__func__);
|
||||
}
|
||||
|
||||
void FetchService::FetchInstance::Cancel() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mFetchDriver) {
|
||||
mFetchDriver->RunAbortAlgorithm();
|
||||
}
|
||||
}
|
||||
|
||||
void FetchService::FetchInstance::OnResponseEnd(
|
||||
FetchDriverObserver::EndReason aReason) {
|
||||
if (aReason == eAborted) {
|
||||
|
@ -226,7 +235,7 @@ void FetchService::CancelFetch(
|
|||
|
||||
auto entry = mFetchInstanceTable.Lookup(aResponsePromise);
|
||||
if (entry) {
|
||||
// TODO: Need to call FetchDriver::RunAbortAlgorithm();
|
||||
entry.Data()->Cancel();
|
||||
entry.Remove();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,8 @@ class FetchService final {
|
|||
|
||||
RefPtr<FetchServiceResponsePromise> Fetch();
|
||||
|
||||
void Cancel();
|
||||
|
||||
/* FetchDriverObserver interface */
|
||||
void OnResponseEnd(FetchDriverObserver::EndReason aReason) override;
|
||||
void OnResponseAvailableInternal(
|
||||
|
@ -99,6 +101,7 @@ class FetchService final {
|
|||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
|
||||
RefPtr<PerformanceStorage> mPerformanceStorage;
|
||||
RefPtr<FetchDriver> mFetchDriver;
|
||||
|
||||
MozPromiseHolder<FetchServiceResponsePromise> mResponsePromiseHolder;
|
||||
};
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/dom/FetchService.h"
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "mozilla/dom/InternalResponse.h"
|
||||
#include "mozilla/dom/PRemoteWorkerControllerChild.h"
|
||||
|
@ -217,15 +218,16 @@ FetchEventOpChild::FetchEventOpChild(
|
|||
: mArgs(std::move(aArgs)),
|
||||
mInterceptedChannel(std::move(aInterceptedChannel)),
|
||||
mRegistration(std::move(aRegistration)),
|
||||
mKeepAliveToken(std::move(aKeepAliveToken)) {
|
||||
if (aPreloadResponseReadyPromise) {
|
||||
mKeepAliveToken(std::move(aKeepAliveToken)),
|
||||
mPreloadResponseReadyPromise(std::move(aPreloadResponseReadyPromise)) {
|
||||
if (mPreloadResponseReadyPromise) {
|
||||
// This promise should be configured to use synchronous dispatch, so if it's
|
||||
// already resolved when we run this code then the callback will be called
|
||||
// synchronously and pass the preload response with the constructor message.
|
||||
//
|
||||
// Note that it's fine to capture the this pointer in the callbacks because
|
||||
// we disconnect the request in Recv__delete__().
|
||||
aPreloadResponseReadyPromise
|
||||
mPreloadResponseReadyPromise
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[this](SafeRefPtr<InternalResponse> aInternalResponse) {
|
||||
|
@ -240,9 +242,11 @@ FetchEventOpChild::FetchEventOpChild(
|
|||
// have to send it in a separate message.
|
||||
SendPreloadResponse(response);
|
||||
}
|
||||
mPreloadResponseReadyPromise = nullptr;
|
||||
mPreloadResponseReadyPromiseRequestHolder.Complete();
|
||||
},
|
||||
[this](const CopyableErrorResult&) {
|
||||
mPreloadResponseReadyPromise = nullptr;
|
||||
mPreloadResponseReadyPromiseRequestHolder.Complete();
|
||||
})
|
||||
->Track(mPreloadResponseReadyPromiseRequestHolder);
|
||||
|
@ -269,6 +273,10 @@ mozilla::ipc::IPCResult FetchEventOpChild::RecvRespondWith(
|
|||
// Preload response is too late to be ready after we receive RespondWith, so
|
||||
// disconnect the promise.
|
||||
mPreloadResponseReadyPromiseRequestHolder.DisconnectIfExists();
|
||||
if (mPreloadResponseReadyPromise) {
|
||||
RefPtr<FetchService> fetchService = FetchService::GetInstance();
|
||||
fetchService->CancelFetch(std::move(mPreloadResponseReadyPromise));
|
||||
}
|
||||
|
||||
switch (aResult.type()) {
|
||||
case ParentToParentFetchEventRespondWithResult::
|
||||
|
@ -328,6 +336,10 @@ mozilla::ipc::IPCResult FetchEventOpChild::Recv__delete__(
|
|||
|
||||
mPromiseHolder.ResolveIfExists(true, __func__);
|
||||
mPreloadResponseReadyPromiseRequestHolder.DisconnectIfExists();
|
||||
if (mPreloadResponseReadyPromise) {
|
||||
RefPtr<FetchService> fetchService = FetchService::GetInstance();
|
||||
fetchService->CancelFetch(std::move(mPreloadResponseReadyPromise));
|
||||
}
|
||||
|
||||
/**
|
||||
* This corresponds to the "Fire Functional Event" algorithm's step 9:
|
||||
|
|
|
@ -83,6 +83,7 @@ class FetchEventOpChild final : public PFetchEventOpChild {
|
|||
bool mWasSent = false;
|
||||
MozPromiseRequestHolder<FetchServiceResponsePromise>
|
||||
mPreloadResponseReadyPromiseRequestHolder;
|
||||
RefPtr<FetchServiceResponsePromise> mPreloadResponseReadyPromise;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
Загрузка…
Ссылка в новой задаче