зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 5 changesets (bug 1351231) for causing fetch related failures. CLOSED TREE
Backed out changeset da5c4a821428 (bug 1351231) Backed out changeset 66b279e5a513 (bug 1351231) Backed out changeset 3eb8fdd0ba6d (bug 1351231) Backed out changeset a1fcf22a2a0e (bug 1351231) Backed out changeset fd2a843599d1 (bug 1351231)
This commit is contained in:
Родитель
255bd963bc
Коммит
7855df7caf
|
@ -300,9 +300,7 @@ skip-if =
|
|||
[browser_net_waterfall-click.js]
|
||||
[browser_net_websocket_stacks.js]
|
||||
[browser_net_worker_stacks.js]
|
||||
skip-if =
|
||||
win10_2004 # Bug 1723573
|
||||
nightly_build # Bug 1351231
|
||||
skip-if = win10_2004 # Bug 1723573
|
||||
[browser_net_ws-basic.js]
|
||||
[browser_net_ws-clear.js]
|
||||
[browser_net_ws-connection-closed.js]
|
||||
|
|
|
@ -9,12 +9,8 @@
|
|||
#include "js/RootingAPI.h"
|
||||
#include "js/Value.h"
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
|
||||
#include "nsDOMString.h"
|
||||
|
@ -45,7 +41,6 @@
|
|||
#include "mozilla/net/CookieJarSettings.h"
|
||||
|
||||
#include "BodyExtractor.h"
|
||||
#include "FetchChild.h"
|
||||
#include "FetchObserver.h"
|
||||
#include "InternalRequest.h"
|
||||
#include "InternalResponse.h"
|
||||
|
@ -604,57 +599,6 @@ already_AddRefed<Promise> FetchRequest(nsIGlobalObject* aGlobal,
|
|||
r->SetSkipServiceWorker();
|
||||
}
|
||||
|
||||
// PFetch gives no benefit for the fetch in the parent process.
|
||||
// Dispatch fetch to the parent process main thread directly for that case.
|
||||
// For child process, dispatch fetch op to the parent.
|
||||
if (StaticPrefs::dom_workers_pFetch_enabled() && !XRE_IsParentProcess()) {
|
||||
RefPtr<FetchChild> actor =
|
||||
FetchChild::Create(worker, p, signalImpl, observer);
|
||||
if (!actor) {
|
||||
NS_WARNING("Could not keep the worker alive.");
|
||||
aRv.Throw(NS_ERROR_DOM_ABORT_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Maybe<ClientInfo> clientInfo(worker->GlobalScope()->GetClientInfo());
|
||||
if (clientInfo.isNothing()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto* backgroundChild =
|
||||
mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
|
||||
Unused << NS_WARN_IF(!backgroundChild->SendPFetchConstructor(actor));
|
||||
|
||||
FetchOpArgs ipcArgs;
|
||||
|
||||
ipcArgs.request() = IPCInternalRequest();
|
||||
r->ToIPCInternalRequest(&(ipcArgs.request()), backgroundChild);
|
||||
|
||||
ipcArgs.principalInfo() = worker->GetPrincipalInfo();
|
||||
ipcArgs.clientInfo() = clientInfo.ref().ToIPC();
|
||||
if (worker->GetBaseURI()) {
|
||||
worker->GetBaseURI()->GetAsciiSpec(ipcArgs.workerScript());
|
||||
}
|
||||
if (worker->GlobalScope()->GetController().isSome()) {
|
||||
ipcArgs.controller() =
|
||||
Some(worker->GlobalScope()->GetController().ref().ToIPC());
|
||||
}
|
||||
if (worker->CookieJarSettings()) {
|
||||
ipcArgs.cookieJarSettings() = Some(worker->CookieJarSettingsArgs());
|
||||
}
|
||||
if (worker->CSPEventListener()) {
|
||||
ipcArgs.hasCSPEventListener() = true;
|
||||
actor->SetCSPEventListener(worker->CSPEventListener());
|
||||
} else {
|
||||
ipcArgs.hasCSPEventListener() = false;
|
||||
}
|
||||
|
||||
actor->DoFetchOp(ipcArgs);
|
||||
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
RefPtr<WorkerFetchResolver> resolver =
|
||||
WorkerFetchResolver::Create(worker, p, signalImpl, observer);
|
||||
if (!resolver) {
|
||||
|
|
|
@ -1,334 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "FetchChild.h"
|
||||
#include "FetchLog.h"
|
||||
#include "FetchObserver.h"
|
||||
#include "InternalResponse.h"
|
||||
#include "Request.h"
|
||||
#include "Response.h"
|
||||
#include "mozilla/ConsoleReportCollector.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/dom/PerformanceTiming.h"
|
||||
#include "mozilla/dom/PerformanceStorage.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/RemoteWorkerChild.h"
|
||||
#include "mozilla/dom/SecurityPolicyViolationEventBinding.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS0(FetchChild)
|
||||
|
||||
mozilla::ipc::IPCResult FetchChild::Recv__delete__(const nsresult&& aResult) {
|
||||
FETCH_LOG(("FetchChild::Recv__delete__ [%p]", this));
|
||||
if (mIsShutdown) {
|
||||
return IPC_OK();
|
||||
}
|
||||
// Shutdown has not been called, so mWorkerRef->Private() should be still
|
||||
// alive.
|
||||
MOZ_ASSERT(mWorkerRef->Private());
|
||||
mWorkerRef->Private()->AssertIsOnWorkerThread();
|
||||
|
||||
if (mPromise->State() == Promise::PromiseState::Pending) {
|
||||
if (NS_FAILED(aResult)) {
|
||||
mPromise->MaybeReject(aResult);
|
||||
if (mFetchObserver) {
|
||||
mFetchObserver->SetState(FetchState::Errored);
|
||||
}
|
||||
} else {
|
||||
mPromise->MaybeResolve(aResult);
|
||||
if (mFetchObserver) {
|
||||
mFetchObserver->SetState(FetchState::Complete);
|
||||
}
|
||||
}
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FetchChild::RecvOnResponseAvailableInternal(
|
||||
ParentToChildInternalResponse&& aResponse) {
|
||||
FETCH_LOG(("FetchChild::RecvOnResponseAvailableInternal [%p]", this));
|
||||
if (mIsShutdown) {
|
||||
return IPC_OK();
|
||||
}
|
||||
// Shutdown has not been called, so mWorkerRef->Private() should be still
|
||||
// alive.
|
||||
MOZ_ASSERT(mWorkerRef->Private());
|
||||
mWorkerRef->Private()->AssertIsOnWorkerThread();
|
||||
SafeRefPtr<InternalResponse> internalResponse =
|
||||
InternalResponse::FromIPC(aResponse);
|
||||
IgnoredErrorResult result;
|
||||
internalResponse->Headers()->SetGuard(HeadersGuardEnum::Immutable, result);
|
||||
MOZ_ASSERT(internalResponse);
|
||||
|
||||
if (internalResponse->Type() != ResponseType::Error) {
|
||||
if (internalResponse->Type() == ResponseType::Opaque) {
|
||||
internalResponse->GeneratePaddingInfo();
|
||||
}
|
||||
|
||||
if (mFetchObserver) {
|
||||
mFetchObserver->SetState(FetchState::Complete);
|
||||
}
|
||||
nsCOMPtr<nsIGlobalObject> global;
|
||||
global = mWorkerRef->Private()->GlobalScope();
|
||||
RefPtr<Response> response =
|
||||
new Response(global, internalResponse.clonePtr(), mSignalImpl);
|
||||
mPromise->MaybeResolve(response);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
FETCH_LOG(
|
||||
("FetchChild::RecvOnResponseAvailableInternal [%p] response type is "
|
||||
"Error(0x%x)",
|
||||
this, static_cast<int32_t>(internalResponse->GetErrorCode())));
|
||||
if (mFetchObserver) {
|
||||
mFetchObserver->SetState(FetchState::Errored);
|
||||
}
|
||||
mPromise->MaybeRejectWithTypeError<MSG_FETCH_FAILED>();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FetchChild::RecvOnResponseEnd(ResponseEndArgs&& aArgs) {
|
||||
FETCH_LOG(("FetchChild::RecvOnResponseEnd [%p]", this));
|
||||
if (mIsShutdown) {
|
||||
return IPC_OK();
|
||||
}
|
||||
// Shutdown has not been called, so mWorkerRef->Private() should be still
|
||||
// alive.
|
||||
MOZ_ASSERT(mWorkerRef->Private());
|
||||
mWorkerRef->Private()->AssertIsOnWorkerThread();
|
||||
|
||||
if (aArgs.timing().isSome()) {
|
||||
const auto& timing = aArgs.timing().ref();
|
||||
RefPtr<PerformanceStorage> performanceStorage =
|
||||
mWorkerRef->Private()->GetPerformanceStorage();
|
||||
if (performanceStorage) {
|
||||
performanceStorage->AddEntry(
|
||||
timing.entryName(), timing.initiatorType(),
|
||||
MakeUnique<PerformanceTimingData>(timing.timingData()));
|
||||
}
|
||||
}
|
||||
|
||||
if (aArgs.endReason() == FetchDriverObserver::eAborted) {
|
||||
FETCH_LOG(
|
||||
("FetchChild::RecvOnResponseEnd [%p] endReason is eAborted", this));
|
||||
if (mFetchObserver) {
|
||||
mFetchObserver->SetState(FetchState::Errored);
|
||||
}
|
||||
mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
Unfollow();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FetchChild::RecvOnDataAvailable() {
|
||||
FETCH_LOG(("FetchChild::RecvOnDataAvailable [%p]", this));
|
||||
if (mIsShutdown) {
|
||||
return IPC_OK();
|
||||
}
|
||||
// Shutdown has not been called, so mWorkerRef->Private() should be still
|
||||
// alive.
|
||||
MOZ_ASSERT(mWorkerRef->Private());
|
||||
mWorkerRef->Private()->AssertIsOnWorkerThread();
|
||||
|
||||
if (mFetchObserver && mFetchObserver->State() == FetchState::Requesting) {
|
||||
mFetchObserver->SetState(FetchState::Responding);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FetchChild::RecvOnFlushConsoleReport(
|
||||
nsTArray<net::ConsoleReportCollected>&& aReports) {
|
||||
FETCH_LOG(("FetchChild::RecvOnFlushConsoleReport [%p]", this));
|
||||
if (mIsShutdown) {
|
||||
return IPC_OK();
|
||||
}
|
||||
// Shutdown has not been called, so mWorkerRef->Private() should be still
|
||||
// alive.
|
||||
MOZ_ASSERT(mWorkerRef->Private());
|
||||
mWorkerRef->Private()->AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(mReporter);
|
||||
|
||||
RefPtr<ThreadSafeWorkerRef> workerRef = mWorkerRef;
|
||||
nsCOMPtr<nsIConsoleReportCollector> reporter = mReporter;
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__, [reports = std::move(aReports), reporter = std::move(reporter),
|
||||
workerRef = std::move(workerRef)]() mutable {
|
||||
for (const auto& report : reports) {
|
||||
reporter->AddConsoleReport(
|
||||
report.errorFlags(), report.category(),
|
||||
static_cast<nsContentUtils::PropertiesFile>(
|
||||
report.propertiesFile()),
|
||||
report.sourceFileURI(), report.lineNumber(),
|
||||
report.columnNumber(), report.messageName(),
|
||||
report.stringParams());
|
||||
}
|
||||
|
||||
if (workerRef->Private()->IsServiceWorker()) {
|
||||
reporter->FlushReportsToConsoleForServiceWorkerScope(
|
||||
workerRef->Private()->ServiceWorkerScope());
|
||||
}
|
||||
|
||||
if (workerRef->Private()->IsSharedWorker()) {
|
||||
workerRef->Private()
|
||||
->GetRemoteWorkerController()
|
||||
->FlushReportsOnMainThread(reporter);
|
||||
}
|
||||
|
||||
reporter->FlushConsoleReports(workerRef->Private()->GetLoadGroup());
|
||||
});
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
SchedulerGroup::Dispatch(TaskCategory::Other, r.forget()));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<FetchChild> FetchChild::Create(WorkerPrivate* aWorkerPrivate,
|
||||
RefPtr<Promise> aPromise,
|
||||
RefPtr<AbortSignalImpl> aSignalImpl,
|
||||
RefPtr<FetchObserver> aObserver) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
RefPtr<FetchChild> actor = MakeRefPtr<FetchChild>(
|
||||
std::move(aPromise), std::move(aSignalImpl), std::move(aObserver));
|
||||
|
||||
RefPtr<StrongWorkerRef> workerRef =
|
||||
StrongWorkerRef::Create(aWorkerPrivate, "FetchChild", [actor]() {
|
||||
FETCH_LOG(("StrongWorkerRef callback"));
|
||||
actor->Shutdown();
|
||||
});
|
||||
if (NS_WARN_IF(!workerRef)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
actor->mWorkerRef = new ThreadSafeWorkerRef(workerRef);
|
||||
if (NS_WARN_IF(!actor->mWorkerRef)) {
|
||||
return nullptr;
|
||||
}
|
||||
return actor;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FetchChild::RecvOnCSPViolationEvent(
|
||||
const nsAString& aJSON) {
|
||||
FETCH_LOG(("FetchChild::RecvOnCSPViolationEvent [%p] aJSON: %s\n", this,
|
||||
NS_ConvertUTF16toUTF8(aJSON).BeginReading()));
|
||||
|
||||
nsString JSON(aJSON);
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(__func__, [JSON]() mutable {
|
||||
SecurityPolicyViolationEventInit violationEventInit;
|
||||
if (NS_WARN_IF(!violationEventInit.Init(JSON))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv =
|
||||
NS_NewURI(getter_AddRefs(uri), violationEventInit.mBlockedURI);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (!observerService) {
|
||||
return;
|
||||
}
|
||||
|
||||
rv = observerService->NotifyObservers(
|
||||
uri, CSP_VIOLATION_TOPIC, violationEventInit.mViolatedDirective.get());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
SchedulerGroup::Dispatch(TaskCategory::Other, r.forget()));
|
||||
|
||||
if (mCSPEventListener) {
|
||||
Unused << NS_WARN_IF(
|
||||
NS_FAILED(mCSPEventListener->OnCSPViolationEvent(aJSON)));
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void FetchChild::SetCSPEventListener(nsICSPEventListener* aListener) {
|
||||
MOZ_ASSERT(aListener && !mCSPEventListener);
|
||||
mCSPEventListener = aListener;
|
||||
}
|
||||
|
||||
FetchChild::FetchChild(RefPtr<Promise>&& aPromise,
|
||||
RefPtr<AbortSignalImpl>&& aSignalImpl,
|
||||
RefPtr<FetchObserver>&& aObserver)
|
||||
: mPromise(std::move(aPromise)),
|
||||
mSignalImpl(std::move(aSignalImpl)),
|
||||
mFetchObserver(std::move(aObserver)),
|
||||
mReporter(new ConsoleReportCollector()) {
|
||||
FETCH_LOG(("FetchChild::FetchChild [%p]", this));
|
||||
}
|
||||
|
||||
void FetchChild::RunAbortAlgorithm() {
|
||||
FETCH_LOG(("FetchChild::RunAbortAlgorithm [%p]", this));
|
||||
if (mIsShutdown) {
|
||||
return;
|
||||
}
|
||||
if (mWorkerRef) {
|
||||
Unused << SendAbortFetchOp();
|
||||
}
|
||||
}
|
||||
|
||||
void FetchChild::DoFetchOp(const FetchOpArgs& aArgs) {
|
||||
FETCH_LOG(("FetchChild::DoFetchOp [%p]", this));
|
||||
if (mSignalImpl) {
|
||||
if (mSignalImpl->Aborted()) {
|
||||
Unused << SendAbortFetchOp();
|
||||
return;
|
||||
}
|
||||
Follow(mSignalImpl);
|
||||
}
|
||||
Unused << SendFetchOp(aArgs);
|
||||
}
|
||||
|
||||
void FetchChild::Shutdown() {
|
||||
FETCH_LOG(("FetchChild::Shutdown [%p]", this));
|
||||
if (mIsShutdown) {
|
||||
return;
|
||||
}
|
||||
mIsShutdown.Flip();
|
||||
|
||||
// If mWorkerRef is nullptr here, that means Recv__delete__() must be called
|
||||
if (!mWorkerRef) {
|
||||
return;
|
||||
}
|
||||
mPromise = nullptr;
|
||||
mFetchObserver = nullptr;
|
||||
Unfollow();
|
||||
mSignalImpl = nullptr;
|
||||
mCSPEventListener = nullptr;
|
||||
Unused << SendAbortFetchOp();
|
||||
mWorkerRef = nullptr;
|
||||
}
|
||||
|
||||
void FetchChild::ActorDestroy(ActorDestroyReason aReason) {
|
||||
FETCH_LOG(("FetchChild::ActorDestroy [%p]", this));
|
||||
mPromise = nullptr;
|
||||
mFetchObserver = nullptr;
|
||||
mSignalImpl = nullptr;
|
||||
mCSPEventListener = nullptr;
|
||||
mWorkerRef = nullptr;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
|
@ -1,76 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_fetchChild_h__
|
||||
#define mozilla_dom_fetchChild_h__
|
||||
|
||||
#include "mozilla/dom/AbortSignal.h"
|
||||
#include "mozilla/dom/AbortFollower.h"
|
||||
#include "mozilla/dom/FlippedOnce.h"
|
||||
#include "mozilla/dom/PFetchChild.h"
|
||||
#include "nsIConsoleReportCollector.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class FetchObserver;
|
||||
class ThreadSafeWorkerRef;
|
||||
class Promise;
|
||||
class WorkerPrivate;
|
||||
|
||||
class FetchChild final : public PFetchChild, public AbortFollower {
|
||||
friend class PFetchChild;
|
||||
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
mozilla::ipc::IPCResult Recv__delete__(const nsresult&& aResult);
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnResponseAvailableInternal(
|
||||
ParentToChildInternalResponse&& aResponse);
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnResponseEnd(ResponseEndArgs&& aArgs);
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnDataAvailable();
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnFlushConsoleReport(
|
||||
nsTArray<net::ConsoleReportCollected>&& aReports);
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnCSPViolationEvent(const nsAString& aJSon);
|
||||
|
||||
void SetCSPEventListener(nsICSPEventListener* aListener);
|
||||
|
||||
static RefPtr<FetchChild> Create(WorkerPrivate* aWorkerPrivate,
|
||||
RefPtr<Promise> aPromise,
|
||||
RefPtr<AbortSignalImpl> aSignalImpl,
|
||||
RefPtr<FetchObserver> aObserver);
|
||||
|
||||
FetchChild(RefPtr<Promise>&& aPromise, RefPtr<AbortSignalImpl>&& aSignalImpl,
|
||||
RefPtr<FetchObserver>&& aObserver);
|
||||
|
||||
// AbortFollower
|
||||
void RunAbortAlgorithm() override;
|
||||
|
||||
void DoFetchOp(const FetchOpArgs& aArgs);
|
||||
|
||||
private:
|
||||
~FetchChild() = default;
|
||||
|
||||
// WorkerPrivate shutdown callback.
|
||||
void Shutdown();
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
RefPtr<ThreadSafeWorkerRef> mWorkerRef;
|
||||
RefPtr<Promise> mPromise;
|
||||
RefPtr<AbortSignalImpl> mSignalImpl;
|
||||
RefPtr<FetchObserver> mFetchObserver;
|
||||
nsCOMPtr<nsICSPEventListener> mCSPEventListener;
|
||||
nsCOMPtr<nsIConsoleReportCollector> mReporter;
|
||||
FlippedOnce<false> mIsShutdown;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif
|
|
@ -38,7 +38,6 @@
|
|||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/PerformanceStorage.h"
|
||||
#include "mozilla/dom/PerformanceTiming.h"
|
||||
#include "mozilla/dom/ServiceWorkerInterceptController.h"
|
||||
#include "mozilla/dom/UserActivation.h"
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/PreloaderBase.h"
|
||||
|
@ -319,8 +318,7 @@ AlternativeDataStreamListener::CheckListenerChain() { return NS_OK; }
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS(FetchDriver, nsIStreamListener, nsIChannelEventSink,
|
||||
nsIInterfaceRequestor, nsIThreadRetargetableStreamListener,
|
||||
nsINetworkInterceptController)
|
||||
nsIInterfaceRequestor, nsIThreadRetargetableStreamListener)
|
||||
|
||||
FetchDriver::FetchDriver(SafeRefPtr<InternalRequest> aRequest,
|
||||
nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup,
|
||||
|
@ -1473,55 +1471,6 @@ void FetchDriver::FinishOnStopRequest(
|
|||
Unfollow();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FetchDriver::ShouldPrepareForIntercept(nsIURI* aURI, nsIChannel* aChannel,
|
||||
bool* aShouldIntercept) {
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
if (mInterceptController) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
return mInterceptController->ShouldPrepareForIntercept(aURI, aChannel,
|
||||
aShouldIntercept);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINetworkInterceptController> controller;
|
||||
NS_QueryNotificationCallbacks(nullptr, mLoadGroup,
|
||||
NS_GET_IID(nsINetworkInterceptController),
|
||||
getter_AddRefs(controller));
|
||||
if (controller) {
|
||||
return controller->ShouldPrepareForIntercept(aURI, aChannel,
|
||||
aShouldIntercept);
|
||||
}
|
||||
|
||||
*aShouldIntercept = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FetchDriver::ChannelIntercepted(nsIInterceptedChannel* aChannel) {
|
||||
if (mInterceptController) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
return mInterceptController->ChannelIntercepted(aChannel);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINetworkInterceptController> controller;
|
||||
NS_QueryNotificationCallbacks(nullptr, mLoadGroup,
|
||||
NS_GET_IID(nsINetworkInterceptController),
|
||||
getter_AddRefs(controller));
|
||||
if (controller) {
|
||||
return controller->ChannelIntercepted(aChannel);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void FetchDriver::EnableNetworkInterceptControl() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mInterceptController);
|
||||
mInterceptController = new ServiceWorkerInterceptController();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
nsIChannel* aNewChannel, uint32_t aFlags,
|
||||
|
@ -1628,9 +1577,7 @@ void FetchDriver::SetController(
|
|||
PerformanceTimingData* FetchDriver::GetPerformanceTimingData(
|
||||
nsAString& aInitiatorType, nsAString& aEntryName) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
if (!mChannel) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(mChannel);
|
||||
|
||||
nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(mChannel);
|
||||
if (!timedChannel) {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsINetworkInterceptController.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIThreadRetargetableStreamListener.h"
|
||||
#include "mozilla/ConsoleReportCollector.h"
|
||||
|
@ -93,7 +92,6 @@ class AlternativeDataStreamListener;
|
|||
class FetchDriver final : public nsIStreamListener,
|
||||
public nsIChannelEventSink,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsINetworkInterceptController,
|
||||
public nsIThreadRetargetableStreamListener,
|
||||
public AbortFollower {
|
||||
public:
|
||||
|
@ -102,7 +100,6 @@ class FetchDriver final : public nsIStreamListener,
|
|||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSINETWORKINTERCEPTCONTROLLER
|
||||
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
|
||||
|
||||
FetchDriver(SafeRefPtr<InternalRequest> aRequest, nsIPrincipal* aPrincipal,
|
||||
|
@ -136,8 +133,6 @@ class FetchDriver final : public nsIStreamListener,
|
|||
void RunAbortAlgorithm() override;
|
||||
void FetchDriverAbortActions(AbortSignalImpl* aSignalImpl);
|
||||
|
||||
void EnableNetworkInterceptControl();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
@ -186,7 +181,6 @@ class FetchDriver final : public nsIStreamListener,
|
|||
bool mResponseAvailableCalled;
|
||||
bool mFetchCalled;
|
||||
#endif
|
||||
nsCOMPtr<nsINetworkInterceptController> mInterceptController;
|
||||
|
||||
friend class AlternativeDataStreamListener;
|
||||
|
||||
|
|
|
@ -1,298 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "FetchLog.h"
|
||||
#include "FetchParent.h"
|
||||
#include "FetchService.h"
|
||||
#include "InternalRequest.h"
|
||||
#include "InternalResponse.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/ClientInfo.h"
|
||||
#include "mozilla/dom/FetchTypes.h"
|
||||
#include "mozilla/dom/PerformanceTimingTypes.h"
|
||||
#include "mozilla/dom/ServiceWorkerDescriptor.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(FetchParent::FetchParentCSPEventListener, nsICSPEventListener)
|
||||
|
||||
FetchParent::FetchParentCSPEventListener::FetchParentCSPEventListener(
|
||||
const nsID& aActorID, nsCOMPtr<nsISerialEventTarget> aEventTarget)
|
||||
: mActorID(aActorID), mEventTarget(aEventTarget) {
|
||||
MOZ_ASSERT(mEventTarget);
|
||||
FETCH_LOG(("FetchParentCSPEventListener [%p] actor ID: %s", this,
|
||||
mActorID.ToString()));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP FetchParent::FetchParentCSPEventListener::OnCSPViolationEvent(
|
||||
const nsAString& aJSON) {
|
||||
AssertIsOnMainThread();
|
||||
FETCH_LOG(("FetchParentCSPEventListener::OnCSPViolationEvent [%p]", this));
|
||||
|
||||
nsAutoString json(aJSON);
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
NS_NewRunnableFunction(__func__, [actorID = mActorID, json]() mutable {
|
||||
FETCH_LOG(
|
||||
("FetchParentCSPEventListener::OnCSPViolationEvent, Runnale"));
|
||||
RefPtr<FetchParent> actor = FetchParent::GetActorByID(actorID);
|
||||
if (actor) {
|
||||
actor->OnCSPViolationEvent(json);
|
||||
}
|
||||
});
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(mEventTarget->Dispatch(r, nsIThread::DISPATCH_NORMAL));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTHashMap<nsIDHashKey, RefPtr<FetchParent>> FetchParent::sActorTable;
|
||||
|
||||
/*static*/
|
||||
RefPtr<FetchParent> FetchParent::GetActorByID(const nsID& aID) {
|
||||
AssertIsOnBackgroundThread();
|
||||
auto entry = sActorTable.Lookup(aID);
|
||||
if (entry) {
|
||||
return entry.Data();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FetchParent::FetchParent() : mID(nsID::GenerateUUID()) {
|
||||
FETCH_LOG(("FetchParent::FetchParent [%p]", this));
|
||||
AssertIsOnBackgroundThread();
|
||||
mBackgroundEventTarget = GetCurrentSerialEventTarget();
|
||||
MOZ_ASSERT(mBackgroundEventTarget);
|
||||
if (!sActorTable.WithEntryHandle(mID, [&](auto&& entry) {
|
||||
if (entry.HasEntry()) {
|
||||
return false;
|
||||
}
|
||||
entry.Insert(this);
|
||||
return true;
|
||||
})) {
|
||||
FETCH_LOG(("FetchParent::FetchParent entry[%p] already exists", this));
|
||||
}
|
||||
}
|
||||
|
||||
FetchParent::~FetchParent() {
|
||||
FETCH_LOG(("FetchParent::~FetchParent [%p]", this));
|
||||
MOZ_ASSERT(!mBackgroundEventTarget);
|
||||
MOZ_ASSERT(!mResponsePromises);
|
||||
MOZ_ASSERT(mActorDestroyed && mIsDone);
|
||||
}
|
||||
|
||||
IPCResult FetchParent::RecvFetchOp(FetchOpArgs&& aArgs) {
|
||||
FETCH_LOG(("FetchParent::RecvFetchOp [%p]", this));
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
MOZ_ASSERT(!mIsDone);
|
||||
if (mActorDestroyed) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mRequest = MakeSafeRefPtr<InternalRequest>(std::move(aArgs.request()));
|
||||
mPrincipalInfo = std::move(aArgs.principalInfo());
|
||||
mWorkerScript = aArgs.workerScript();
|
||||
mClientInfo = Some(ClientInfo(aArgs.clientInfo()));
|
||||
if (aArgs.controller().isSome()) {
|
||||
mController = Some(ServiceWorkerDescriptor(aArgs.controller().ref()));
|
||||
}
|
||||
mCookieJarSettings = aArgs.cookieJarSettings();
|
||||
mNeedOnDataAvailable = aArgs.needOnDataAvailable();
|
||||
mHasCSPEventListener = aArgs.hasCSPEventListener();
|
||||
|
||||
if (mHasCSPEventListener) {
|
||||
mCSPEventListener =
|
||||
MakeRefPtr<FetchParentCSPEventListener>(mID, mBackgroundEventTarget);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mPromise);
|
||||
mPromise = new GenericPromise::Private(__func__);
|
||||
|
||||
RefPtr<FetchParent> self = this;
|
||||
mPromise->Then(
|
||||
mBackgroundEventTarget, __func__,
|
||||
[self](const bool&& result) mutable {
|
||||
FETCH_LOG(
|
||||
("FetchParent::RecvFetchOp [%p] Success Callback", self.get()));
|
||||
AssertIsOnBackgroundThread();
|
||||
self->mIsDone = true;
|
||||
self->mPromise = nullptr;
|
||||
if (!self->mActorDestroyed && !self->mExtendForCSPEventListener) {
|
||||
FETCH_LOG(("FetchParent::RecvFetchOp [%p] Send__delete__(NS_OK)",
|
||||
self.get()));
|
||||
Unused << NS_WARN_IF(!self->Send__delete__(self, NS_OK));
|
||||
}
|
||||
},
|
||||
[self](const nsresult&& aErr) mutable {
|
||||
FETCH_LOG(
|
||||
("FetchParent::RecvFetchOp [%p] Failure Callback", self.get()));
|
||||
AssertIsOnBackgroundThread();
|
||||
self->mIsDone = true;
|
||||
self->mPromise = nullptr;
|
||||
if (!self->mActorDestroyed) {
|
||||
FETCH_LOG(("FetchParent::RecvFetchOp [%p] Send__delete__(aErr)",
|
||||
self.get()));
|
||||
Unused << NS_WARN_IF(!self->Send__delete__(self, aErr));
|
||||
}
|
||||
});
|
||||
|
||||
RefPtr<nsIRunnable> r = NS_NewRunnableFunction(__func__, [self]() mutable {
|
||||
FETCH_LOG(
|
||||
("FetchParent::RecvFetchOp [%p], Main Thread Runnable", self.get()));
|
||||
AssertIsOnMainThread();
|
||||
if (self->mIsDone) {
|
||||
MOZ_ASSERT(!self->mResponsePromises);
|
||||
MOZ_ASSERT(self->mPromise);
|
||||
FETCH_LOG(
|
||||
("FetchParent::RecvFetchOp [%p], Main Thread Runnable, "
|
||||
"already aborted",
|
||||
self.get()));
|
||||
self->mPromise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__);
|
||||
return;
|
||||
}
|
||||
RefPtr<FetchService> fetchService = FetchService::GetInstance();
|
||||
MOZ_ASSERT(fetchService);
|
||||
MOZ_ASSERT(!self->mResponsePromises);
|
||||
self->mResponsePromises =
|
||||
fetchService->Fetch(AsVariant(FetchService::WorkerFetchArgs(
|
||||
{self->mRequest.clonePtr(), self->mPrincipalInfo,
|
||||
self->mWorkerScript, self->mClientInfo, self->mController,
|
||||
self->mCookieJarSettings, self->mNeedOnDataAvailable,
|
||||
self->mCSPEventListener, self->mBackgroundEventTarget,
|
||||
self->mID})));
|
||||
|
||||
self->mResponsePromises->GetResponseEndPromise()->Then(
|
||||
self->mBackgroundEventTarget, __func__,
|
||||
[self](ResponseEndArgs&& aArgs) mutable {
|
||||
MOZ_ASSERT(self->mPromise);
|
||||
self->mPromise->Resolve(true, __func__);
|
||||
self->mResponsePromises = nullptr;
|
||||
self->mPromise = nullptr;
|
||||
},
|
||||
[self](CopyableErrorResult&& aErr) mutable {
|
||||
MOZ_ASSERT(self->mPromise);
|
||||
self->mPromise->Reject(aErr.StealNSResult(), __func__);
|
||||
self->mResponsePromises = nullptr;
|
||||
self->mPromise = nullptr;
|
||||
});
|
||||
});
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
SchedulerGroup::Dispatch(TaskCategory::Other, r.forget()));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FetchParent::RecvAbortFetchOp() {
|
||||
FETCH_LOG(("FetchParent::RecvAbortFetchOp [%p]", this));
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (mIsDone) {
|
||||
FETCH_LOG(("FetchParent::RecvAbortFetchOp [%p], Already aborted", this));
|
||||
return IPC_OK();
|
||||
}
|
||||
mIsDone = true;
|
||||
|
||||
if (mResponsePromises) {
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__, [promises = std::move(mResponsePromises)]() mutable {
|
||||
FETCH_LOG(("FetchParent::RecvAbortFetchOp Runnable"));
|
||||
AssertIsOnMainThread();
|
||||
RefPtr<FetchService> fetchService = FetchService::GetInstance();
|
||||
MOZ_ASSERT(fetchService);
|
||||
fetchService->CancelFetch(std::move(promises));
|
||||
});
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
SchedulerGroup::Dispatch(TaskCategory::Other, r.forget()));
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void FetchParent::OnResponseAvailableInternal(
|
||||
SafeRefPtr<InternalResponse>&& aResponse) {
|
||||
FETCH_LOG(("FetchParent::OnResponseAvailableInternal [%p]", this));
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aResponse);
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
// To monitor the stream status between processes, response's body can not be
|
||||
// serialized as RemoteLazyInputStream. Such that stream close can be
|
||||
// propagated to FetchDriver in the parent process.
|
||||
aResponse->SetSerializeAsLazy(false);
|
||||
|
||||
// CSP violation notification is asynchronous. Extending the FetchParent's
|
||||
// life cycle for the notificaiton.
|
||||
if (aResponse->Type() == ResponseType::Error &&
|
||||
aResponse->GetErrorCode() == NS_ERROR_CONTENT_BLOCKED &&
|
||||
mCSPEventListener) {
|
||||
FETCH_LOG(
|
||||
("FetchParent::OnResponseAvailableInternal [%p] "
|
||||
"NS_ERROR_CONTENT_BLOCKED",
|
||||
this));
|
||||
mExtendForCSPEventListener = true;
|
||||
}
|
||||
|
||||
Unused << SendOnResponseAvailableInternal(
|
||||
aResponse->ToParentToChildInternalResponse(WrapNotNull(Manager())));
|
||||
}
|
||||
|
||||
void FetchParent::OnResponseEnd(const ResponseEndArgs& aArgs) {
|
||||
FETCH_LOG(("FetchParent::OnResponseEnd [%p]", this));
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
Unused << SendOnResponseEnd(aArgs);
|
||||
}
|
||||
|
||||
void FetchParent::OnDataAvailable() {
|
||||
FETCH_LOG(("FetchParent::OnDataAvailable [%p]", this));
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
Unused << SendOnDataAvailable();
|
||||
}
|
||||
|
||||
void FetchParent::OnFlushConsoleReport(
|
||||
const nsTArray<net::ConsoleReportCollected>& aReports) {
|
||||
FETCH_LOG(("FetchParent::OnFlushConsoleReport [%p]", this));
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
Unused << SendOnFlushConsoleReport(aReports);
|
||||
}
|
||||
|
||||
void FetchParent::ActorDestroy(ActorDestroyReason aReason) {
|
||||
FETCH_LOG(("FetchParent::ActorDestroy [%p]", this));
|
||||
AssertIsOnBackgroundThread();
|
||||
mActorDestroyed = true;
|
||||
auto entry = sActorTable.Lookup(mID);
|
||||
if (entry) {
|
||||
entry.Remove();
|
||||
FETCH_LOG(("FetchParent::ActorDestroy entry [%p] removed", this));
|
||||
}
|
||||
// Force to abort the existing fetch.
|
||||
// Actor can be destoried by shutdown when still fetching.
|
||||
RecvAbortFetchOp();
|
||||
mBackgroundEventTarget = nullptr;
|
||||
}
|
||||
|
||||
nsICSPEventListener* FetchParent::GetCSPEventListener() {
|
||||
return mCSPEventListener;
|
||||
}
|
||||
|
||||
void FetchParent::OnCSPViolationEvent(const nsAString& aJSON) {
|
||||
FETCH_LOG(("FetchParent::OnCSPViolationEvent [%p]", this));
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mHasCSPEventListener);
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
Unused << SendOnCSPViolationEvent(aJSON);
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
|
@ -1,104 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_fetchParent_h__
|
||||
#define mozilla_dom_fetchParent_h__
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/PFetchParent.h"
|
||||
#include "mozilla/dom/SafeRefPtr.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsID.h"
|
||||
#include "nsISerialEventTarget.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTHashMap.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class ClientInfo;
|
||||
class FetchServicePromises;
|
||||
class InternalRequest;
|
||||
class InternalResponse;
|
||||
class ServiceWorkerDescriptor;
|
||||
|
||||
class FetchParent final : public PFetchParent {
|
||||
friend class PFetchParent;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchParent, override);
|
||||
|
||||
mozilla::ipc::IPCResult RecvFetchOp(FetchOpArgs&& aArgs);
|
||||
|
||||
mozilla::ipc::IPCResult RecvAbortFetchOp();
|
||||
|
||||
FetchParent();
|
||||
|
||||
static RefPtr<FetchParent> GetActorByID(const nsID& aID);
|
||||
|
||||
void OnResponseAvailableInternal(SafeRefPtr<InternalResponse>&& aResponse);
|
||||
|
||||
void OnResponseEnd(const ResponseEndArgs& aArgs);
|
||||
|
||||
void OnDataAvailable();
|
||||
|
||||
void OnFlushConsoleReport(
|
||||
const nsTArray<net::ConsoleReportCollected>& aReports);
|
||||
|
||||
class FetchParentCSPEventListener final : public nsICSPEventListener {
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSICSPEVENTLISTENER
|
||||
|
||||
FetchParentCSPEventListener(const nsID& aActorID,
|
||||
nsCOMPtr<nsISerialEventTarget> aEventTarget);
|
||||
|
||||
private:
|
||||
~FetchParentCSPEventListener() = default;
|
||||
|
||||
nsID mActorID;
|
||||
nsCOMPtr<nsISerialEventTarget> mEventTarget;
|
||||
};
|
||||
|
||||
nsICSPEventListener* GetCSPEventListener();
|
||||
|
||||
void OnCSPViolationEvent(const nsAString& aJSON);
|
||||
|
||||
private:
|
||||
~FetchParent();
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
// The map of FetchParent and ID. Should only access in background thread.
|
||||
static nsTHashMap<nsIDHashKey, RefPtr<FetchParent>> sActorTable;
|
||||
|
||||
// The unique ID of the FetchParent
|
||||
nsID mID;
|
||||
SafeRefPtr<InternalRequest> mRequest;
|
||||
RefPtr<FetchServicePromises> mResponsePromises;
|
||||
RefPtr<GenericPromise::Private> mPromise;
|
||||
PrincipalInfo mPrincipalInfo;
|
||||
nsCString mWorkerScript;
|
||||
Maybe<ClientInfo> mClientInfo;
|
||||
Maybe<ServiceWorkerDescriptor> mController;
|
||||
Maybe<CookieJarSettingsArgs> mCookieJarSettings;
|
||||
nsCOMPtr<nsICSPEventListener> mCSPEventListener;
|
||||
bool mNeedOnDataAvailable{false};
|
||||
bool mHasCSPEventListener{false};
|
||||
bool mExtendForCSPEventListener{false};
|
||||
|
||||
Atomic<bool> mIsDone{false};
|
||||
Atomic<bool> mActorDestroyed{false};
|
||||
|
||||
nsCOMPtr<nsISerialEventTarget> mBackgroundEventTarget;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif
|
|
@ -3,9 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "FetchLog.h"
|
||||
#include "FetchParent.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsICookieJarSettings.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsILoadInfo.h"
|
||||
|
@ -18,18 +16,14 @@
|
|||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/ClientInfo.h"
|
||||
#include "mozilla/dom/FetchService.h"
|
||||
#include "mozilla/dom/InternalRequest.h"
|
||||
#include "mozilla/dom/InternalResponse.h"
|
||||
#include "mozilla/dom/PerformanceStorage.h"
|
||||
#include "mozilla/dom/PerformanceTiming.h"
|
||||
#include "mozilla/dom/ServiceWorkerDescriptor.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/net/CookieJarSettings.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
|
@ -39,9 +33,8 @@ mozilla::LazyLogModule gFetchLog("Fetch");
|
|||
|
||||
FetchServicePromises::FetchServicePromises()
|
||||
: mAvailablePromise(
|
||||
MakeRefPtr<FetchServiceResponseAvailablePromise::Private>(__func__)),
|
||||
mEndPromise(
|
||||
MakeRefPtr<FetchServiceResponseEndPromise::Private>(__func__)) {
|
||||
new FetchServiceResponseAvailablePromise::Private(__func__)),
|
||||
mEndPromise(new FetchServiceResponseEndPromise::Private(__func__)) {
|
||||
mAvailablePromise->UseSynchronousTaskDispatch(__func__);
|
||||
mEndPromise->UseSynchronousTaskDispatch(__func__);
|
||||
}
|
||||
|
@ -86,26 +79,25 @@ void FetchServicePromises::RejectResponseEndPromise(
|
|||
|
||||
// FetchInstance
|
||||
|
||||
nsresult FetchService::FetchInstance::Initialize(FetchArgs&& aArgs) {
|
||||
FetchService::FetchInstance::FetchInstance(SafeRefPtr<InternalRequest> aRequest)
|
||||
: mRequest(std::move(aRequest)) {}
|
||||
|
||||
FetchService::FetchInstance::~FetchInstance() = default;
|
||||
|
||||
nsresult FetchService::FetchInstance::Initialize(nsIChannel* aChannel) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!aArgs.is<UnknownArgs>() && mArgs.is<UnknownArgs>());
|
||||
|
||||
mArgs = std::move(aArgs);
|
||||
|
||||
// Get needed information for FetchDriver from passed-in channel.
|
||||
if (mArgs.is<NavigationPreloadArgs>()) {
|
||||
mRequest = mArgs.as<NavigationPreloadArgs>().mRequest.clonePtr();
|
||||
nsIChannel* channel = mArgs.as<NavigationPreloadArgs>().mChannel;
|
||||
FETCH_LOG(("FetchInstance::Initialize [%p] request[%p], channel[%p]", this,
|
||||
mRequest.unsafeGetRawPtr(), channel));
|
||||
if (aChannel) {
|
||||
FETCH_LOG(("FetchInstance::Initialize [%p] aChannel[%p]", this, aChannel));
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
MOZ_ASSERT(loadInfo);
|
||||
|
||||
nsCOMPtr<nsIURI> channelURI;
|
||||
rv = channel->GetURI(getter_AddRefs(channelURI));
|
||||
rv = aChannel->GetURI(getter_AddRefs(channelURI));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -113,7 +105,7 @@ nsresult FetchService::FetchInstance::Initialize(FetchArgs&& aArgs) {
|
|||
nsIScriptSecurityManager* securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
if (securityManager) {
|
||||
securityManager->GetChannelResultPrincipal(channel,
|
||||
securityManager->GetChannelResultPrincipal(aChannel,
|
||||
getter_AddRefs(mPrincipal));
|
||||
}
|
||||
|
||||
|
@ -122,7 +114,7 @@ nsresult FetchService::FetchInstance::Initialize(FetchArgs&& aArgs) {
|
|||
}
|
||||
|
||||
// Get loadGroup from channel
|
||||
rv = channel->GetLoadGroup(getter_AddRefs(mLoadGroup));
|
||||
rv = aChannel->GetLoadGroup(getter_AddRefs(mLoadGroup));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -142,28 +134,10 @@ nsresult FetchService::FetchInstance::Initialize(FetchArgs&& aArgs) {
|
|||
// Get PerformanceStorage from channel
|
||||
mPerformanceStorage = loadInfo->GetPerformanceStorage();
|
||||
} else {
|
||||
mIsWorkerFetch = true;
|
||||
mRequest = mArgs.as<WorkerFetchArgs>().mRequest.clonePtr();
|
||||
|
||||
FETCH_LOG(("FetchInstance::Initialize [%p] request[%p]", this,
|
||||
mRequest.unsafeGetRawPtr()));
|
||||
|
||||
auto principalOrErr =
|
||||
PrincipalInfoToPrincipal(mArgs.as<WorkerFetchArgs>().mPrincipalInfo);
|
||||
if (principalOrErr.isErr()) {
|
||||
return principalOrErr.unwrapErr();
|
||||
}
|
||||
mPrincipal = principalOrErr.unwrap();
|
||||
nsresult rv = NS_NewLoadGroup(getter_AddRefs(mLoadGroup), mPrincipal);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mArgs.as<WorkerFetchArgs>().mCookieJarSettings.isSome()) {
|
||||
net::CookieJarSettings::Deserialize(
|
||||
mArgs.as<WorkerFetchArgs>().mCookieJarSettings.ref(),
|
||||
getter_AddRefs(mCookieJarSettings));
|
||||
}
|
||||
// TODO:
|
||||
// Get information from InternalRequest and PFetch IPC parameters.
|
||||
// This will be implemented in bug 1351231.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -196,21 +170,6 @@ RefPtr<FetchServicePromises> FetchService::FetchInstance::Fetch() {
|
|||
false // IsTrackingFetch
|
||||
);
|
||||
|
||||
if (mIsWorkerFetch) {
|
||||
auto& args = mArgs.as<WorkerFetchArgs>();
|
||||
mFetchDriver->SetWorkerScript(args.mWorkerScript);
|
||||
MOZ_ASSERT(args.mClientInfo.isSome());
|
||||
mFetchDriver->SetClientInfo(args.mClientInfo.ref());
|
||||
mFetchDriver->SetController(args.mController);
|
||||
if (args.mCSPEventListener) {
|
||||
mFetchDriver->SetCSPEventListener(args.mCSPEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
mFetchDriver->EnableNetworkInterceptControl();
|
||||
|
||||
mPromises = MakeRefPtr<FetchServicePromises>();
|
||||
|
||||
// Call FetchDriver::Fetch to start fetching.
|
||||
// Pass AbortSignalImpl as nullptr since we no need support AbortSignalImpl
|
||||
// with FetchService. AbortSignalImpl related information should be passed
|
||||
|
@ -223,6 +182,8 @@ RefPtr<FetchServicePromises> FetchService::FetchInstance::Fetch() {
|
|||
return FetchService::NetworkErrorResponse(rv);
|
||||
}
|
||||
|
||||
mPromises = MakeRefPtr<FetchServicePromises>();
|
||||
|
||||
return mPromises;
|
||||
}
|
||||
|
||||
|
@ -236,155 +197,74 @@ void FetchService::FetchInstance::Cancel() {
|
|||
mFetchDriver->RunAbortAlgorithm();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPromises);
|
||||
if (mPromises) {
|
||||
mPromises->ResolveResponseAvailablePromise(
|
||||
InternalResponse::NetworkError(NS_ERROR_DOM_ABORT_ERR), __func__);
|
||||
|
||||
mPromises->ResolveResponseAvailablePromise(
|
||||
InternalResponse::NetworkError(NS_ERROR_DOM_ABORT_ERR), __func__);
|
||||
|
||||
mPromises->ResolveResponseEndPromise(
|
||||
ResponseEndArgs(FetchDriverObserver::eAborted, Nothing()), __func__);
|
||||
mPromises->ResolveResponseEndPromise(
|
||||
ResponseEndArgs(FetchDriverObserver::eAborted, Nothing()), __func__);
|
||||
mPromises = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void FetchService::FetchInstance::OnResponseEnd(
|
||||
FetchDriverObserver::EndReason aReason,
|
||||
JS::Handle<JS::Value> aReasonDetails) {
|
||||
FETCH_LOG(("FetchInstance::OnResponseEnd [%p] %s", this,
|
||||
aReason == eAborted ? "eAborted" : "eNetworking"));
|
||||
|
||||
// Get response timing form FetchDriver
|
||||
Maybe<ResponseTiming> responseTiming;
|
||||
ResponseTiming timing;
|
||||
UniquePtr<PerformanceTimingData> performanceTiming(
|
||||
mFetchDriver->GetPerformanceTimingData(timing.initiatorType(),
|
||||
timing.entryName()));
|
||||
if (performanceTiming != nullptr) {
|
||||
timing.timingData() = performanceTiming->ToIPC();
|
||||
if (!mIsWorkerFetch) {
|
||||
// Force replace initiatorType for ServiceWorkerNavgationPreload.
|
||||
timing.initiatorType() = u"navigation"_ns;
|
||||
}
|
||||
responseTiming = Some(timing);
|
||||
}
|
||||
|
||||
if (mIsWorkerFetch) {
|
||||
FlushConsoleReport();
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__, [endArgs = ResponseEndArgs(aReason, responseTiming),
|
||||
actorID = mArgs.as<WorkerFetchArgs>().mActorID]() {
|
||||
FETCH_LOG(("FetchParent::OnResponseEnd, Runnable"));
|
||||
RefPtr<FetchParent> actor = FetchParent::GetActorByID(actorID);
|
||||
if (actor) {
|
||||
actor->OnResponseEnd(std::move(endArgs));
|
||||
}
|
||||
});
|
||||
MOZ_ALWAYS_SUCCEEDS(mArgs.as<WorkerFetchArgs>().mEventTarget->Dispatch(
|
||||
r, nsIThread::DISPATCH_NORMAL));
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPromises);
|
||||
|
||||
// Resolve the ResponseEndPromise
|
||||
mPromises->ResolveResponseEndPromise(ResponseEndArgs(aReason, responseTiming),
|
||||
__func__);
|
||||
|
||||
FETCH_LOG(("FetchInstance::OnResponseEnd [%p]", this));
|
||||
if (aReason == eAborted) {
|
||||
FETCH_LOG(("FetchInstance::OnResponseEnd end with eAborted"));
|
||||
if (mPromises) {
|
||||
mPromises->ResolveResponseEndPromise(
|
||||
ResponseEndArgs(FetchDriverObserver::eAborted, Nothing()), __func__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the FetchInstance from FetchInstanceTable
|
||||
RefPtr<FetchService> fetchService = FetchService::GetInstance();
|
||||
MOZ_ASSERT(fetchService);
|
||||
auto entry = fetchService->mFetchInstanceTable.Lookup(mPromises);
|
||||
if (entry) {
|
||||
if (mPromises) {
|
||||
// Remove the FetchInstance from FetchInstanceTable
|
||||
RefPtr<FetchService> fetchService = FetchService::GetInstance();
|
||||
MOZ_ASSERT(fetchService);
|
||||
auto entry = fetchService->mFetchInstanceTable.Lookup(mPromises);
|
||||
MOZ_ASSERT(entry);
|
||||
entry.Remove();
|
||||
FETCH_LOG(
|
||||
("FetchInstance::OnResponseEnd entry of responsePromise[%p] is "
|
||||
("FetchInstance::OnResponseEnd entry[%p] of FetchInstance[%p] is "
|
||||
"removed",
|
||||
mPromises.get()));
|
||||
mPromises.get(), this));
|
||||
|
||||
// Get PerformanceTimingData from FetchDriver.
|
||||
ResponseTiming timing;
|
||||
UniquePtr<PerformanceTimingData> performanceTiming(
|
||||
mFetchDriver->GetPerformanceTimingData(timing.initiatorType(),
|
||||
timing.entryName()));
|
||||
if (performanceTiming != nullptr) {
|
||||
timing.timingData() = performanceTiming->ToIPC();
|
||||
}
|
||||
|
||||
timing.initiatorType() = u"navigation"_ns;
|
||||
|
||||
// Resolve the ResponseEndPromise
|
||||
mPromises->ResolveResponseEndPromise(ResponseEndArgs(aReason, Some(timing)),
|
||||
__func__);
|
||||
// Release promises
|
||||
mPromises = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void FetchService::FetchInstance::OnResponseAvailableInternal(
|
||||
SafeRefPtr<InternalResponse> aResponse) {
|
||||
FETCH_LOG(("FetchInstance::OnResponseAvailableInternal [%p]", this));
|
||||
mResponse = std::move(aResponse);
|
||||
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
mResponse->GetUnfilteredBody(getter_AddRefs(body));
|
||||
FETCH_LOG(
|
||||
("FetchInstance::OnResponseAvailableInternal [%p] response body: %p",
|
||||
this, body.get()));
|
||||
|
||||
if (mIsWorkerFetch) {
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__, [response = mResponse.clonePtr(),
|
||||
actorID = mArgs.as<WorkerFetchArgs>().mActorID]() mutable {
|
||||
FETCH_LOG(("FetchInstance::OnResponseAvailableInternal Runnable"));
|
||||
RefPtr<FetchParent> actor = FetchParent::GetActorByID(actorID);
|
||||
if (actor) {
|
||||
actor->OnResponseAvailableInternal(std::move(response));
|
||||
}
|
||||
});
|
||||
MOZ_ALWAYS_SUCCEEDS(mArgs.as<WorkerFetchArgs>().mEventTarget->Dispatch(
|
||||
r, nsIThread::DISPATCH_NORMAL));
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPromises);
|
||||
|
||||
// Resolve the ResponseAvailablePromise
|
||||
mPromises->ResolveResponseAvailablePromise(mResponse.clonePtr(), __func__);
|
||||
}
|
||||
|
||||
bool FetchService::FetchInstance::NeedOnDataAvailable() {
|
||||
if (mArgs.is<WorkerFetchArgs>()) {
|
||||
return mArgs.as<WorkerFetchArgs>().mNeedOnDataAvailable;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FetchService::FetchInstance::OnDataAvailable() {
|
||||
FETCH_LOG(("FetchInstance::OnDataAvailable [%p]", this));
|
||||
|
||||
if (!NeedOnDataAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIsWorkerFetch) {
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__, [actorID = mArgs.as<WorkerFetchArgs>().mActorID]() {
|
||||
FETCH_LOG(("FetchParent::OnDataAvailable, Runnable"));
|
||||
RefPtr<FetchParent> actor = FetchParent::GetActorByID(actorID);
|
||||
if (actor) {
|
||||
actor->OnDataAvailable();
|
||||
}
|
||||
});
|
||||
MOZ_ALWAYS_SUCCEEDS(mArgs.as<WorkerFetchArgs>().mEventTarget->Dispatch(
|
||||
r, nsIThread::DISPATCH_NORMAL));
|
||||
if (mPromises) {
|
||||
// Resolve the ResponseAvailablePromise
|
||||
mPromises->ResolveResponseAvailablePromise(std::move(aResponse), __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void FetchService::FetchInstance::FlushConsoleReport() {
|
||||
FETCH_LOG(("FetchInstance::FlushConsoleReport [%p]", this));
|
||||
|
||||
if (mIsWorkerFetch) {
|
||||
if (!mReporter) {
|
||||
return;
|
||||
}
|
||||
nsTArray<net::ConsoleReportCollected> reports;
|
||||
mReporter->StealConsoleReports(reports);
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__, [actorID = mArgs.as<WorkerFetchArgs>().mActorID,
|
||||
consoleReports = std::move(reports)]() {
|
||||
FETCH_LOG(("FetchParent::FlushConsolReport, Runnable"));
|
||||
RefPtr<FetchParent> actor = FetchParent::GetActorByID(actorID);
|
||||
if (actor) {
|
||||
actor->OnFlushConsoleReport(std::move(consoleReports));
|
||||
}
|
||||
});
|
||||
MOZ_ALWAYS_SUCCEEDS(mArgs.as<WorkerFetchArgs>().mEventTarget->Dispatch(
|
||||
r, nsIThread::DISPATCH_NORMAL));
|
||||
}
|
||||
}
|
||||
// TODO:
|
||||
// Following methods would not be used for navigation preload, but would be used
|
||||
// with PFetch. They will be implemented in bug 1351231.
|
||||
bool FetchService::FetchInstance::NeedOnDataAvailable() { return false; }
|
||||
void FetchService::FetchInstance::OnDataAvailable() {}
|
||||
void FetchService::FetchInstance::FlushConsoleReport() {}
|
||||
|
||||
// FetchService
|
||||
|
||||
|
@ -502,30 +382,31 @@ NS_IMETHODIMP FetchService::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<FetchServicePromises> FetchService::Fetch(FetchArgs&& aArgs) {
|
||||
RefPtr<FetchServicePromises> FetchService::Fetch(
|
||||
SafeRefPtr<InternalRequest> aRequest, nsIChannel* aChannel) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
FETCH_LOG(("FetchService::Fetch (%s)", aArgs.is<NavigationPreloadArgs>()
|
||||
? "NavigationPreload"
|
||||
: "WorkerFetch"));
|
||||
FETCH_LOG(("FetchService::Fetch aRequest[%p], aChannel[%p], mOffline: %s",
|
||||
aRequest.unsafeGetRawPtr(), aChannel,
|
||||
mOffline ? "true" : "false"));
|
||||
|
||||
if (mOffline) {
|
||||
FETCH_LOG(("FetchService::Fetch network offline"));
|
||||
return NetworkErrorResponse(NS_ERROR_OFFLINE);
|
||||
}
|
||||
|
||||
// Create FetchInstance
|
||||
RefPtr<FetchInstance> fetch = MakeRefPtr<FetchInstance>();
|
||||
RefPtr<FetchInstance> fetch = MakeRefPtr<FetchInstance>(aRequest.clonePtr());
|
||||
|
||||
// Call FetchInstance::Initialize() to get needed information for FetchDriver,
|
||||
nsresult rv = fetch->Initialize(std::move(aArgs));
|
||||
nsresult rv = fetch->Initialize(aChannel);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NetworkErrorResponse(rv);
|
||||
}
|
||||
|
||||
// Call FetchInstance::Fetch() to start an asynchronous fetching.
|
||||
RefPtr<FetchServicePromises> promises = fetch->Fetch();
|
||||
MOZ_ASSERT(promises);
|
||||
|
||||
if (!promises->GetResponseAvailablePromise()->IsResolved()) {
|
||||
// Insert the created FetchInstance into FetchInstanceTable.
|
||||
|
@ -546,7 +427,7 @@ RefPtr<FetchServicePromises> FetchService::Fetch(FetchArgs&& aArgs) {
|
|||
return promises;
|
||||
}
|
||||
|
||||
void FetchService::CancelFetch(const RefPtr<FetchServicePromises>&& aPromises) {
|
||||
void FetchService::CancelFetch(RefPtr<FetchServicePromises>&& aPromises) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aPromises);
|
||||
|
@ -557,6 +438,7 @@ void FetchService::CancelFetch(const RefPtr<FetchServicePromises>&& aPromises) {
|
|||
// Notice any modifications here before entry.Remove() probably should be
|
||||
// reflected to Observe() offline case.
|
||||
entry.Data()->Cancel();
|
||||
|
||||
entry.Remove();
|
||||
FETCH_LOG(
|
||||
("FetchService::CancelFetch entry [%p] removed", aPromises.get()));
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
#include "mozilla/dom/FetchTypes.h"
|
||||
#include "mozilla/dom/PerformanceTimingTypes.h"
|
||||
#include "mozilla/dom/SafeRefPtr.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
|
||||
class nsILoadGroup;
|
||||
class nsIPrincipal;
|
||||
|
@ -26,8 +24,6 @@ namespace mozilla::dom {
|
|||
|
||||
class InternalRequest;
|
||||
class InternalResponse;
|
||||
class ClientInfo;
|
||||
class ServiceWorkerDescriptor;
|
||||
|
||||
using FetchServiceResponse = SafeRefPtr<InternalResponse>;
|
||||
using FetchServiceResponseAvailablePromise =
|
||||
|
@ -76,29 +72,6 @@ class FetchService final : public nsIObserver {
|
|||
NS_DECL_ISUPPORTS;
|
||||
NS_DECL_NSIOBSERVER;
|
||||
|
||||
struct NavigationPreloadArgs {
|
||||
SafeRefPtr<InternalRequest> mRequest;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
};
|
||||
|
||||
struct WorkerFetchArgs {
|
||||
SafeRefPtr<InternalRequest> mRequest;
|
||||
mozilla::ipc::PrincipalInfo mPrincipalInfo;
|
||||
nsCString mWorkerScript;
|
||||
Maybe<ClientInfo> mClientInfo;
|
||||
Maybe<ServiceWorkerDescriptor> mController;
|
||||
Maybe<net::CookieJarSettingsArgs> mCookieJarSettings;
|
||||
bool mNeedOnDataAvailable;
|
||||
nsCOMPtr<nsICSPEventListener> mCSPEventListener;
|
||||
nsCOMPtr<nsISerialEventTarget> mEventTarget;
|
||||
nsID mActorID;
|
||||
};
|
||||
|
||||
struct UnknownArgs {};
|
||||
|
||||
using FetchArgs =
|
||||
Variant<NavigationPreloadArgs, WorkerFetchArgs, UnknownArgs>;
|
||||
|
||||
static already_AddRefed<FetchService> GetInstance();
|
||||
|
||||
static RefPtr<FetchServicePromises> NetworkErrorResponse(nsresult aRv);
|
||||
|
@ -107,9 +80,10 @@ class FetchService final : public nsIObserver {
|
|||
|
||||
// This method creates a FetchInstance to trigger fetch.
|
||||
// The created FetchInstance is saved in mFetchInstanceTable
|
||||
RefPtr<FetchServicePromises> Fetch(FetchArgs&& aArgs);
|
||||
RefPtr<FetchServicePromises> Fetch(SafeRefPtr<InternalRequest> aRequest,
|
||||
nsIChannel* aChannel = nullptr);
|
||||
|
||||
void CancelFetch(const RefPtr<FetchServicePromises>&& aPromises);
|
||||
void CancelFetch(RefPtr<FetchServicePromises>&& aPromises);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -120,15 +94,22 @@ class FetchService final : public nsIObserver {
|
|||
* FetchInstance triggers fetch by instancing a FetchDriver with proper
|
||||
* initialization. The general usage flow of FetchInstance is as follows
|
||||
*
|
||||
* RefPtr<FetchInstance> fetch = MakeRefPtr<FetchInstance>();
|
||||
* fetch->Initialize(FetchArgs args);
|
||||
* RefPtr<FetchInstance> fetch = MakeRefPtr<FetchInstance>(aResquest);
|
||||
* fetch->Initialize();
|
||||
* RefPtr<FetchServicePromises> fetch->Fetch();
|
||||
*/
|
||||
class FetchInstance final : public FetchDriverObserver {
|
||||
public:
|
||||
FetchInstance() = default;
|
||||
explicit FetchInstance(SafeRefPtr<InternalRequest> aRequest);
|
||||
|
||||
nsresult Initialize(FetchArgs&& aArgs);
|
||||
// This method is used for initialize the fetch.
|
||||
// It accepts a nsIChannel for initialization, this is for the navigation
|
||||
// preload case since there has already been an intercepted channel for
|
||||
// dispatching fetch event, and needed information can be gotten from the
|
||||
// intercepted channel.
|
||||
// For other case, the fetch needed information be created according to the
|
||||
// mRequest
|
||||
nsresult Initialize(nsIChannel* aChannel = nullptr);
|
||||
|
||||
RefPtr<FetchServicePromises> Fetch();
|
||||
|
||||
|
@ -144,18 +125,17 @@ class FetchService final : public nsIObserver {
|
|||
void FlushConsoleReport() override;
|
||||
|
||||
private:
|
||||
~FetchInstance() = default;
|
||||
~FetchInstance();
|
||||
|
||||
SafeRefPtr<InternalRequest> mRequest;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
|
||||
RefPtr<PerformanceStorage> mPerformanceStorage;
|
||||
FetchArgs mArgs{AsVariant(FetchService::UnknownArgs())};
|
||||
RefPtr<FetchDriver> mFetchDriver;
|
||||
SafeRefPtr<InternalResponse> mResponse;
|
||||
|
||||
RefPtr<FetchServicePromises> mPromises;
|
||||
bool mIsWorkerFetch{false};
|
||||
};
|
||||
|
||||
~FetchService();
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "mozilla/RemoteLazyInputStreamStorage.h"
|
||||
#include "mozilla/dom/FetchTypes.h"
|
||||
#include "mozilla/dom/IPCBlob.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
|
@ -35,12 +34,7 @@ NotNull<nsCOMPtr<nsIInputStream>> ToInputStream(
|
|||
NotNull<nsCOMPtr<nsIInputStream>> ToInputStream(
|
||||
const ParentToChildStream& aStream) {
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
nsCOMPtr<nsIInputStream> result;
|
||||
if (aStream.type() == ParentToChildStream::TRemoteLazyInputStream) {
|
||||
result = aStream.get_RemoteLazyInputStream();
|
||||
} else {
|
||||
result = DeserializeIPCStream(aStream.get_IPCStream());
|
||||
}
|
||||
nsCOMPtr<nsIInputStream> result = aStream.stream();
|
||||
return WrapNotNull(result);
|
||||
}
|
||||
|
||||
|
@ -56,20 +50,11 @@ ParentToParentStream ToParentToParentStream(
|
|||
|
||||
ParentToChildStream ToParentToChildStream(
|
||||
const NotNull<nsCOMPtr<nsIInputStream>>& aStream, int64_t aStreamSize,
|
||||
NotNull<mozilla::ipc::PBackgroundParent*> aBackgroundParent,
|
||||
bool aSerializeAsLazy) {
|
||||
NotNull<mozilla::ipc::PBackgroundParent*> aBackgroundParent) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
ParentToChildStream result;
|
||||
if (aSerializeAsLazy) {
|
||||
result = RemoteLazyInputStream::WrapStream(aStream.get());
|
||||
} else {
|
||||
nsCOMPtr<nsIInputStream> stream(aStream.get());
|
||||
mozilla::ipc::IPCStream ipcStream;
|
||||
Unused << NS_WARN_IF(
|
||||
!mozilla::ipc::SerializeIPCStream(stream.forget(), ipcStream, false));
|
||||
result = ipcStream;
|
||||
}
|
||||
result.stream() = RemoteLazyInputStream::WrapStream(aStream.get());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,8 +40,7 @@ ParentToParentStream ToParentToParentStream(
|
|||
// process. Can only be called in the parent process.
|
||||
ParentToChildStream ToParentToChildStream(
|
||||
const NotNull<nsCOMPtr<nsIInputStream>>& aStream, int64_t aStreamSize,
|
||||
NotNull<mozilla::ipc::PBackgroundParent*> aBackgroundParent,
|
||||
bool aSerializeAsLazy = true);
|
||||
NotNull<mozilla::ipc::PBackgroundParent*> aBackgroundParent);
|
||||
|
||||
// Convert a ParentToParentStream to a ParentToChildStream. Can only be called
|
||||
// in the parent process.
|
||||
|
|
|
@ -18,7 +18,6 @@ using RequestRedirect from "mozilla/dom/RequestBinding.h";
|
|||
using ResponseType from "mozilla/dom/ResponseBinding.h";
|
||||
using struct nsID from "nsID.h";
|
||||
using FetchDriverObserver::EndReason from "mozilla/dom/FetchDriver.h";
|
||||
using nsILoadInfo::CrossOriginEmbedderPolicy from "nsILoadInfo.h";
|
||||
[RefCounted] using class mozilla::RemoteLazyInputStream from "mozilla/RemoteLazyInputStream.h";
|
||||
[RefCounted] using class nsITransportSecurityInfo from "nsITransportSecurityInfo.h";
|
||||
|
||||
|
@ -35,9 +34,8 @@ struct ParentToParentStream {
|
|||
nsID uuid;
|
||||
};
|
||||
|
||||
union ParentToChildStream {
|
||||
RemoteLazyInputStream;
|
||||
IPCStream;
|
||||
struct ParentToChildStream {
|
||||
RemoteLazyInputStream stream;
|
||||
};
|
||||
|
||||
struct ChildToParentStream {
|
||||
|
@ -61,7 +59,6 @@ struct IPCInternalRequest {
|
|||
uint32_t contentPolicyType;
|
||||
nsString referrer;
|
||||
ReferrerPolicy referrerPolicy;
|
||||
ReferrerPolicy environmentReferrerPolicy;
|
||||
RequestMode requestMode;
|
||||
RequestCredentials requestCredentials;
|
||||
RequestCache cacheMode;
|
||||
|
@ -73,7 +70,6 @@ struct IPCInternalRequest {
|
|||
uint32_t interceptionContentPolicyType;
|
||||
RedirectHistoryEntryInfo[] interceptionRedirectChain;
|
||||
bool interceptionFromThirdParty;
|
||||
CrossOriginEmbedderPolicy embedderPolicy;
|
||||
};
|
||||
|
||||
struct InternalResponseMetadata {
|
||||
|
@ -87,8 +83,6 @@ struct InternalResponseMetadata {
|
|||
nsCString alternativeDataType;
|
||||
nsITransportSecurityInfo securityInfo;
|
||||
PrincipalInfo? principalInfo;
|
||||
nsCString bodyBlobURISpec;
|
||||
nsString bodyLocalPath;
|
||||
};
|
||||
|
||||
struct ParentToParentInternalResponse {
|
||||
|
|
|
@ -53,7 +53,6 @@ SafeRefPtr<InternalRequest> InternalRequest::GetRequestConstructorCopy(
|
|||
|
||||
copy->mPreferredAlternativeDataType = mPreferredAlternativeDataType;
|
||||
copy->mSkipWasmCaching = mSkipWasmCaching;
|
||||
copy->mEmbedderPolicy = mEmbedderPolicy;
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
@ -141,7 +140,6 @@ InternalRequest::InternalRequest(const InternalRequest& aOther,
|
|||
mUnsafeRequest(aOther.mUnsafeRequest),
|
||||
mUseURLCredentials(aOther.mUseURLCredentials),
|
||||
mContentPolicyTypeOverridden(aOther.mContentPolicyTypeOverridden),
|
||||
mEmbedderPolicy(aOther.mEmbedderPolicy),
|
||||
mInterceptionContentPolicyType(aOther.mInterceptionContentPolicyType),
|
||||
mInterceptionRedirectChain(aOther.mInterceptionRedirectChain),
|
||||
mInterceptionFromThirdParty(aOther.mInterceptionFromThirdParty) {
|
||||
|
@ -165,14 +163,12 @@ InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
|
|||
static_cast<nsContentPolicyType>(aIPCRequest.contentPolicyType())),
|
||||
mReferrer(aIPCRequest.referrer()),
|
||||
mReferrerPolicy(aIPCRequest.referrerPolicy()),
|
||||
mEnvironmentReferrerPolicy(aIPCRequest.environmentReferrerPolicy()),
|
||||
mMode(aIPCRequest.requestMode()),
|
||||
mCredentialsMode(aIPCRequest.requestCredentials()),
|
||||
mCacheMode(aIPCRequest.cacheMode()),
|
||||
mRedirectMode(aIPCRequest.requestRedirect()),
|
||||
mIntegrity(aIPCRequest.integrity()),
|
||||
mFragment(aIPCRequest.fragment()),
|
||||
mEmbedderPolicy(aIPCRequest.embedderPolicy()),
|
||||
mInterceptionContentPolicyType(static_cast<nsContentPolicyType>(
|
||||
aIPCRequest.interceptionContentPolicyType())),
|
||||
mInterceptionRedirectChain(aIPCRequest.interceptionRedirectChain()),
|
||||
|
@ -190,52 +186,11 @@ InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
|
|||
|
||||
const Maybe<BodyStreamVariant>& body = aIPCRequest.body();
|
||||
|
||||
if (!XRE_IsParentProcess()) {
|
||||
if (body) {
|
||||
MOZ_ASSERT(body->type() == BodyStreamVariant::TParentToChildStream);
|
||||
mBodyStream = body->get_ParentToChildStream().get_RemoteLazyInputStream();
|
||||
}
|
||||
} else {
|
||||
if (body) {
|
||||
MOZ_ASSERT(body->type() == BodyStreamVariant::TChildToParentStream);
|
||||
mBodyStream =
|
||||
DeserializeIPCStream(body->get_ChildToParentStream().stream());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InternalRequest::ToIPCInternalRequest(
|
||||
IPCInternalRequest* aIPCRequest, mozilla::ipc::PBackgroundChild* aManager) {
|
||||
aIPCRequest->method() = mMethod;
|
||||
for (const auto& url : mURLList) {
|
||||
aIPCRequest->urlList().AppendElement(url);
|
||||
}
|
||||
mHeaders->ToIPC(aIPCRequest->headers(), aIPCRequest->headersGuard());
|
||||
aIPCRequest->bodySize() = mBodyLength;
|
||||
aIPCRequest->preferredAlternativeDataType() = mPreferredAlternativeDataType;
|
||||
aIPCRequest->contentPolicyType() = mContentPolicyType;
|
||||
aIPCRequest->referrer() = mReferrer;
|
||||
aIPCRequest->referrerPolicy() = mReferrerPolicy;
|
||||
aIPCRequest->environmentReferrerPolicy() = mEnvironmentReferrerPolicy;
|
||||
aIPCRequest->requestMode() = mMode;
|
||||
aIPCRequest->requestCredentials() = mCredentialsMode;
|
||||
aIPCRequest->cacheMode() = mCacheMode;
|
||||
aIPCRequest->requestRedirect() = mRedirectMode;
|
||||
aIPCRequest->integrity() = mIntegrity;
|
||||
aIPCRequest->fragment() = mFragment;
|
||||
aIPCRequest->embedderPolicy() = mEmbedderPolicy;
|
||||
|
||||
if (mPrincipalInfo) {
|
||||
aIPCRequest->principalInfo() = Some(*mPrincipalInfo);
|
||||
}
|
||||
|
||||
if (mBodyStream) {
|
||||
nsCOMPtr<nsIInputStream> body = mBodyStream;
|
||||
aIPCRequest->body().emplace(ChildToParentStream());
|
||||
DebugOnly<bool> ok = mozilla::ipc::SerializeIPCStream(
|
||||
body.forget(), aIPCRequest->body()->get_ChildToParentStream().stream(),
|
||||
/* aAllowLazy */ false);
|
||||
MOZ_ASSERT(ok);
|
||||
// This constructor is (currently) only used for parent -> child communication
|
||||
// (constructed on the child side).
|
||||
if (body) {
|
||||
MOZ_ASSERT(body->type() == BodyStreamVariant::TParentToChildStream);
|
||||
mBodyStream = body->get_ParentToChildStream().stream();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ using mozilla::net::RedirectHistoryEntryInfo;
|
|||
namespace mozilla {
|
||||
|
||||
namespace ipc {
|
||||
class PBackgroundChild;
|
||||
class PrincipalInfo;
|
||||
} // namespace ipc
|
||||
|
||||
|
@ -98,9 +97,6 @@ class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
|
|||
|
||||
explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
|
||||
|
||||
void ToIPCInternalRequest(IPCInternalRequest* aIPCRequest,
|
||||
mozilla::ipc::PBackgroundChild* aManager);
|
||||
|
||||
SafeRefPtr<InternalRequest> Clone();
|
||||
|
||||
void GetMethod(nsCString& aMethod) const { aMethod.Assign(mMethod); }
|
||||
|
|
|
@ -90,11 +90,6 @@ template <typename T>
|
|||
aIPCResponse.metadata().principalInfo().ref()));
|
||||
}
|
||||
|
||||
nsAutoCString bodyBlobURISpec(aIPCResponse.metadata().bodyBlobURISpec());
|
||||
response->SetBodyBlobURISpec(bodyBlobURISpec);
|
||||
nsAutoString bodyLocalPath(aIPCResponse.metadata().bodyLocalPath());
|
||||
response->SetBodyLocalPath(bodyLocalPath);
|
||||
|
||||
switch (aIPCResponse.metadata().type()) {
|
||||
case ResponseType::Basic:
|
||||
response = response->BasicResponse();
|
||||
|
@ -129,17 +124,13 @@ InternalResponseMetadata InternalResponse::GetMetadata() {
|
|||
Maybe<mozilla::ipc::PrincipalInfo> principalInfo =
|
||||
mPrincipalInfo ? Some(*mPrincipalInfo) : Nothing();
|
||||
|
||||
nsAutoCString bodyBlobURISpec(BodyBlobURISpec());
|
||||
nsAutoString bodyLocalPath(BodyLocalPath());
|
||||
|
||||
// Note: all the arguments are copied rather than moved, which would be more
|
||||
// efficient, because there's no move-friendly constructor generated.
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo(mChannelInfo.SecurityInfo());
|
||||
return InternalResponseMetadata(
|
||||
mType, GetUnfilteredURLList(), GetUnfilteredStatus(),
|
||||
GetUnfilteredStatusText(), headersGuard, headers, mErrorCode,
|
||||
GetAlternativeDataType(), securityInfo, principalInfo, bodyBlobURISpec,
|
||||
bodyLocalPath);
|
||||
GetAlternativeDataType(), securityInfo, principalInfo);
|
||||
}
|
||||
|
||||
void InternalResponse::ToChildToParentInternalResponse(
|
||||
|
@ -195,31 +186,6 @@ InternalResponse::ToParentToParentInternalResponse() {
|
|||
return result;
|
||||
}
|
||||
|
||||
ParentToChildInternalResponse InternalResponse::ToParentToChildInternalResponse(
|
||||
NotNull<mozilla::ipc::PBackgroundParent*> aBackgroundParent) {
|
||||
ParentToChildInternalResponse result(GetMetadata(), Nothing(),
|
||||
UNKNOWN_BODY_SIZE, Nothing());
|
||||
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
int64_t bodySize;
|
||||
GetUnfilteredBody(getter_AddRefs(body), &bodySize);
|
||||
|
||||
if (body) {
|
||||
result.body() = Some(ToParentToChildStream(
|
||||
WrapNotNull(body), bodySize, aBackgroundParent, mSerializeAsLazy));
|
||||
result.bodySize() = bodySize;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> alternativeBody = TakeAlternativeBody();
|
||||
if (alternativeBody) {
|
||||
result.alternativeBody() = Some(
|
||||
ToParentToChildStream(WrapNotNull(alternativeBody), UNKNOWN_BODY_SIZE,
|
||||
aBackgroundParent, mSerializeAsLazy));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SafeRefPtr<InternalResponse> InternalResponse::Clone(CloneType aCloneType) {
|
||||
SafeRefPtr<InternalResponse> clone = CreateIncompleteCopy();
|
||||
clone->mCloned = (mCloned = true);
|
||||
|
|
|
@ -57,9 +57,6 @@ class InternalResponse final : public AtomicSafeRefCounted<InternalResponse> {
|
|||
|
||||
ParentToParentInternalResponse ToParentToParentInternalResponse();
|
||||
|
||||
ParentToChildInternalResponse ToParentToChildInternalResponse(
|
||||
NotNull<mozilla::ipc::PBackgroundParent*> aBackgroundParent);
|
||||
|
||||
enum CloneType {
|
||||
eCloneInputStream,
|
||||
eDontCloneInputStream,
|
||||
|
@ -311,9 +308,6 @@ class InternalResponse final : public AtomicSafeRefCounted<InternalResponse> {
|
|||
|
||||
bool HasBeenCloned() const { return mCloned; }
|
||||
|
||||
void SetSerializeAsLazy(bool aAllow) { mSerializeAsLazy = aAllow; }
|
||||
bool CanSerializeAsLazy() const { return mSerializeAsLazy; }
|
||||
|
||||
void InitChannelInfo(nsIChannel* aChannel) {
|
||||
mChannelInfo.InitFromChannel(aChannel);
|
||||
}
|
||||
|
@ -343,8 +337,6 @@ class InternalResponse final : public AtomicSafeRefCounted<InternalResponse> {
|
|||
|
||||
SafeRefPtr<InternalResponse> Unfiltered();
|
||||
|
||||
InternalResponseMetadata GetMetadata();
|
||||
|
||||
~InternalResponse();
|
||||
|
||||
private:
|
||||
|
@ -359,6 +351,8 @@ class InternalResponse final : public AtomicSafeRefCounted<InternalResponse> {
|
|||
template <typename T>
|
||||
static SafeRefPtr<InternalResponse> FromIPCTemplate(const T& aIPCResponse);
|
||||
|
||||
InternalResponseMetadata GetMetadata();
|
||||
|
||||
ResponseType mType;
|
||||
// A response has an associated url list (a list of zero or more fetch URLs).
|
||||
// Unless stated otherwise, it is the empty list. The current url is the last
|
||||
|
@ -383,7 +377,6 @@ class InternalResponse final : public AtomicSafeRefCounted<InternalResponse> {
|
|||
nsCOMPtr<nsIInputStream> mAlternativeBody;
|
||||
nsMainThreadPtrHandle<nsICacheInfoChannel> mCacheInfoChannel;
|
||||
bool mCloned;
|
||||
bool mSerializeAsLazy{true};
|
||||
|
||||
public:
|
||||
static constexpr int64_t UNKNOWN_BODY_SIZE = -1;
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
|
||||
include ClientIPCTypes;
|
||||
include FetchTypes;
|
||||
include IPCServiceWorkerDescriptor;
|
||||
include NeckoChannelParams;
|
||||
include PBackgroundSharedTypes;
|
||||
include PerformanceTimingTypes;
|
||||
|
||||
using FetchDriverObserver::EndReason from "mozilla/dom/FetchDriver.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct FetchOpArgs{
|
||||
IPCInternalRequest request;
|
||||
PrincipalInfo principalInfo;
|
||||
nsCString workerScript;
|
||||
IPCClientInfo clientInfo;
|
||||
IPCServiceWorkerDescriptor? controller;
|
||||
CookieJarSettingsArgs? cookieJarSettings;
|
||||
bool needOnDataAvailable;
|
||||
bool hasCSPEventListener;
|
||||
};
|
||||
|
||||
protocol PFetch {
|
||||
manager PBackground;
|
||||
|
||||
parent:
|
||||
async FetchOp(FetchOpArgs aArgs);
|
||||
|
||||
async AbortFetchOp();
|
||||
|
||||
child:
|
||||
async OnResponseAvailableInternal(ParentToChildInternalResponse aResponse);
|
||||
|
||||
async OnResponseEnd(ResponseEndArgs aResponseEndArgs);
|
||||
|
||||
async OnDataAvailable();
|
||||
|
||||
async OnFlushConsoleReport(ConsoleReportCollected[] aReports);
|
||||
|
||||
async OnCSPViolationEvent(nsString aJSON);
|
||||
|
||||
async __delete__(nsresult aResult);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -11,11 +11,9 @@ EXPORTS.mozilla.dom += [
|
|||
"BodyExtractor.h",
|
||||
"ChannelInfo.h",
|
||||
"Fetch.h",
|
||||
"FetchChild.h",
|
||||
"FetchDriver.h",
|
||||
"FetchIPCTypes.h",
|
||||
"FetchObserver.h",
|
||||
"FetchParent.h",
|
||||
"FetchService.h",
|
||||
"FetchStreamReader.h",
|
||||
"FetchStreamUtils.h",
|
||||
|
@ -32,10 +30,8 @@ UNIFIED_SOURCES += [
|
|||
"BodyExtractor.cpp",
|
||||
"ChannelInfo.cpp",
|
||||
"Fetch.cpp",
|
||||
"FetchChild.cpp",
|
||||
"FetchDriver.cpp",
|
||||
"FetchObserver.cpp",
|
||||
"FetchParent.cpp",
|
||||
"FetchService.cpp",
|
||||
"FetchStreamReader.cpp",
|
||||
"FetchStreamUtils.cpp",
|
||||
|
@ -50,7 +46,6 @@ UNIFIED_SOURCES += [
|
|||
|
||||
IPDL_SOURCES += [
|
||||
"FetchTypes.ipdlh",
|
||||
"PFetch.ipdl",
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
|
|
@ -160,7 +160,7 @@ ParentToParentFetchEventRespondWithResult ToParentToParent(
|
|||
RemoteLazyInputStream::WrapStream(aBodyStream);
|
||||
MOZ_DIAGNOSTIC_ASSERT(stream);
|
||||
|
||||
copyRequest.body().ref().get_ParentToChildStream() = stream;
|
||||
copyRequest.body().ref().get_ParentToChildStream().stream() = stream;
|
||||
}
|
||||
|
||||
Unused << aManager->SendPFetchEventOpProxyConstructor(actor, copyArgs);
|
||||
|
|
|
@ -324,7 +324,6 @@ Result<IPCInternalRequest, nsresult> GetIPCInternalRequest(
|
|||
|
||||
nsAutoString referrer;
|
||||
ReferrerPolicy referrerPolicy = ReferrerPolicy::_empty;
|
||||
ReferrerPolicy environmentReferrerPolicy = ReferrerPolicy::_empty;
|
||||
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo = httpChannel->GetReferrerInfo();
|
||||
if (referrerInfo) {
|
||||
|
@ -394,18 +393,14 @@ Result<IPCInternalRequest, nsresult> GetIPCInternalRequest(
|
|||
&isThirdPartyChannel));
|
||||
}
|
||||
|
||||
nsILoadInfo::CrossOriginEmbedderPolicy embedderPolicy =
|
||||
loadInfo->GetLoadingEmbedderPolicy();
|
||||
|
||||
// Note: all the arguments are copied rather than moved, which would be more
|
||||
// efficient, because there's no move-friendly constructor generated.
|
||||
return IPCInternalRequest(
|
||||
method, {spec}, ipcHeadersGuard, ipcHeaders, Nothing(), -1,
|
||||
alternativeDataType, contentPolicyType, referrer, referrerPolicy,
|
||||
environmentReferrerPolicy, requestMode, requestCredentials, cacheMode,
|
||||
requestRedirect, integrity, fragment, principalInfo,
|
||||
interceptionPrincipalInfo, contentPolicyType, redirectChain,
|
||||
isThirdPartyChannel, embedderPolicy);
|
||||
requestMode, requestCredentials, cacheMode, requestRedirect, integrity,
|
||||
fragment, principalInfo, interceptionPrincipalInfo, contentPolicyType,
|
||||
redirectChain, isThirdPartyChannel);
|
||||
}
|
||||
|
||||
nsresult MaybeStoreStreamForBackgroundThread(nsIInterceptedChannel* aChannel,
|
||||
|
@ -1566,8 +1561,7 @@ RefPtr<FetchServicePromises> ServiceWorkerPrivate::SetupNavigationPreload(
|
|||
MOZ_ALWAYS_SUCCEEDS(
|
||||
aChannel->GetChannel(getter_AddRefs(underlyingChannel)));
|
||||
RefPtr<FetchService> fetchService = FetchService::GetInstance();
|
||||
return fetchService->Fetch(AsVariant(FetchService::NavigationPreloadArgs{
|
||||
std::move(preloadRequest), underlyingChannel}));
|
||||
return fetchService->Fetch(std::move(preloadRequest), underlyingChannel);
|
||||
}
|
||||
return FetchService::NetworkErrorResponse(NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
|
|
@ -71,6 +71,8 @@ WorkerCSPEventListener::WorkerCSPEventListener()
|
|||
|
||||
NS_IMETHODIMP
|
||||
WorkerCSPEventListener::OnCSPViolationEvent(const nsAString& aJSON) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mWorkerRef) {
|
||||
return NS_OK;
|
||||
|
@ -79,26 +81,9 @@ WorkerCSPEventListener::OnCSPViolationEvent(const nsAString& aJSON) {
|
|||
WorkerPrivate* workerPrivate = mWorkerRef->GetUnsafePrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
RefPtr<WorkerCSPEventRunnable> runnable =
|
||||
new WorkerCSPEventRunnable(workerPrivate, aJSON);
|
||||
runnable->Dispatch();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
SecurityPolicyViolationEventInit violationEventInit;
|
||||
if (NS_WARN_IF(!violationEventInit.Init(aJSON))) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
RefPtr<mozilla::dom::Event> event =
|
||||
mozilla::dom::SecurityPolicyViolationEvent::Constructor(
|
||||
workerPrivate->GlobalScope(), u"securitypolicyviolation"_ns,
|
||||
violationEventInit);
|
||||
event->SetTrusted(true);
|
||||
|
||||
workerPrivate->GlobalScope()->DispatchEvent(*event);
|
||||
RefPtr<WorkerCSPEventRunnable> runnable =
|
||||
new WorkerCSPEventRunnable(workerPrivate, aJSON);
|
||||
runnable->Dispatch();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "mozilla/OriginTrials.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/ChannelInfo.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
|
||||
|
@ -63,10 +62,6 @@ struct WorkerLoadInfoData {
|
|||
// Taken from the parent context.
|
||||
nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
|
||||
|
||||
// The CookieJarSettingsArgs of mCookieJarSettings.
|
||||
// This is specific for accessing on worker thread.
|
||||
net::CookieJarSettingsArgs mCookieJarSettingsArgs;
|
||||
|
||||
nsCOMPtr<nsIScriptContext> mScriptContext;
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
|
||||
|
|
|
@ -2753,9 +2753,6 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
|
|||
loadInfo.mHasStorageAccessPermissionGranted =
|
||||
aParent->HasStorageAccessPermissionGranted();
|
||||
loadInfo.mCookieJarSettings = aParent->CookieJarSettings();
|
||||
if (loadInfo.mCookieJarSettings) {
|
||||
loadInfo.mCookieJarSettingsArgs = aParent->CookieJarSettingsArgs();
|
||||
}
|
||||
loadInfo.mOriginAttributes = aParent->GetOriginAttributes();
|
||||
loadInfo.mServiceWorkersTestingInWindow =
|
||||
aParent->ServiceWorkersTestingInWindow();
|
||||
|
@ -2913,11 +2910,6 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
|
|||
loadInfo.mIsThirdPartyContextToTopWindow =
|
||||
AntiTrackingUtils::IsThirdPartyWindow(globalWindow, nullptr);
|
||||
loadInfo.mCookieJarSettings = document->CookieJarSettings();
|
||||
if (loadInfo.mCookieJarSettings) {
|
||||
auto* cookieJarSettings =
|
||||
net::CookieJarSettings::Cast(loadInfo.mCookieJarSettings);
|
||||
cookieJarSettings->Serialize(loadInfo.mCookieJarSettingsArgs);
|
||||
}
|
||||
StoragePrincipalHelper::GetRegularPrincipalOriginAttributes(
|
||||
document, loadInfo.mOriginAttributes);
|
||||
loadInfo.mParentController = globalWindow->GetController();
|
||||
|
@ -2972,9 +2964,6 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
|
|||
loadInfo.mLoadingPrincipal,
|
||||
"Unusual situation - we have no document or CookieJarSettings");
|
||||
MOZ_ASSERT(loadInfo.mCookieJarSettings);
|
||||
auto* cookieJarSettings =
|
||||
net::CookieJarSettings::Cast(loadInfo.mCookieJarSettings);
|
||||
cookieJarSettings->Serialize(loadInfo.mCookieJarSettingsArgs);
|
||||
|
||||
loadInfo.mOriginAttributes = OriginAttributes();
|
||||
loadInfo.mIsThirdPartyContextToTopWindow = false;
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "mozilla/dom/workerinternals/JSSettings.h"
|
||||
#include "mozilla/dom/workerinternals/Queue.h"
|
||||
#include "mozilla/dom/JSExecutionManager.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
#include "mozilla/StaticPrefs_extensions.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIChannel.h"
|
||||
|
@ -873,11 +872,6 @@ class WorkerPrivate final
|
|||
return mLoadInfo.mCookieJarSettings;
|
||||
}
|
||||
|
||||
const net::CookieJarSettingsArgs& CookieJarSettingsArgs() const {
|
||||
MOZ_ASSERT(mLoadInfo.mCookieJarSettings);
|
||||
return mLoadInfo.mCookieJarSettingsArgs;
|
||||
}
|
||||
|
||||
const OriginAttributes& GetOriginAttributes() const {
|
||||
return mLoadInfo.mOriginAttributes;
|
||||
}
|
||||
|
|
|
@ -374,7 +374,6 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread(RemoteWorkerData&& aData) {
|
|||
info.mShouldResistFingerprinting = aData.shouldResistFingerprinting();
|
||||
net::CookieJarSettings::Deserialize(aData.cookieJarSettings(),
|
||||
getter_AddRefs(info.mCookieJarSettings));
|
||||
info.mCookieJarSettingsArgs = aData.cookieJarSettings();
|
||||
|
||||
// Default CSP permissions for now. These will be overrided if necessary
|
||||
// based on the script CSP headers during load in ScriptLoader.
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/dom/EndpointForReportParent.h"
|
||||
#include "mozilla/dom/FetchParent.h"
|
||||
#include "mozilla/dom/FileCreatorParent.h"
|
||||
#include "mozilla/dom/FileSystemManagerParentFactory.h"
|
||||
#include "mozilla/dom/FileSystemRequestParent.h"
|
||||
|
@ -1484,10 +1483,6 @@ BackgroundParentImpl::AllocPLockManagerParent(
|
|||
aClientId);
|
||||
}
|
||||
|
||||
already_AddRefed<dom::PFetchParent> BackgroundParentImpl::AllocPFetchParent() {
|
||||
return MakeAndAddRef<dom::FetchParent>();
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::net::PWebSocketConnectionParent>
|
||||
BackgroundParentImpl::AllocPWebSocketConnectionParent(
|
||||
const uint32_t& aListenerId) {
|
||||
|
|
|
@ -415,8 +415,6 @@ class BackgroundParentImpl : public PBackgroundParent {
|
|||
|
||||
already_AddRefed<PLockManagerParent> AllocPLockManagerParent(
|
||||
const ContentPrincipalInfo& aPrincipalInfo, const nsID& aClientId) final;
|
||||
|
||||
already_AddRefed<PFetchParent> AllocPFetchParent() override;
|
||||
};
|
||||
|
||||
} // namespace mozilla::ipc
|
||||
|
|
|
@ -53,7 +53,6 @@ include protocol PVsync;
|
|||
include protocol PRemoteDecoderManager;
|
||||
include protocol PWebSocketConnection;
|
||||
include protocol PWebTransport;
|
||||
include protocol PFetch;
|
||||
|
||||
include DOMTypes;
|
||||
include IPCBlob;
|
||||
|
@ -132,7 +131,6 @@ sync protocol PBackground
|
|||
manages PUDPSocket;
|
||||
manages PVerifySSLServerCert;
|
||||
manages PVsync;
|
||||
manages PFetch;
|
||||
|
||||
parent:
|
||||
// Only called at startup during mochitests to check the basic infrastructure.
|
||||
|
@ -323,8 +321,6 @@ parent:
|
|||
|
||||
async PIPCClientCerts();
|
||||
|
||||
async PFetch();
|
||||
|
||||
child:
|
||||
async PCache();
|
||||
async PCacheStreamControl();
|
||||
|
|
|
@ -3829,11 +3829,6 @@
|
|||
value: false
|
||||
mirror: always
|
||||
|
||||
- name: dom.workers.pFetch.enabled
|
||||
type: RelaxedAtomicBool
|
||||
value: @IS_NIGHTLY_BUILD@
|
||||
mirror: always
|
||||
|
||||
- name: dom.workers.requestAnimationFrame
|
||||
type: RelaxedAtomicBool
|
||||
value: true
|
||||
|
|
|
@ -157,6 +157,9 @@ add_task(async function test_network_markers_service_worker_register() {
|
|||
|
||||
// Let's look at all pairs and make sure we requested all expected files.
|
||||
const parentStopMarkers = parentPairs.map(([_, stopMarker]) => stopMarker);
|
||||
const serviceWorkerStopMarkers = serviceWorkerPairs.map(
|
||||
([_, stopMarker]) => stopMarker
|
||||
);
|
||||
|
||||
// These are the files cached by the service worker. We should see markers
|
||||
// for both the parent thread and the service worker thread.
|
||||
|
@ -172,6 +175,9 @@ add_task(async function test_network_markers_service_worker_register() {
|
|||
const parentMarker = parentStopMarkers.find(
|
||||
marker => marker.data.URI === expectedFile
|
||||
);
|
||||
const serviceWorkerMarker = serviceWorkerStopMarkers.find(
|
||||
marker => marker.data.URI === expectedFile
|
||||
);
|
||||
|
||||
const expectedProperties = {
|
||||
name: Expect.stringMatches(
|
||||
|
@ -199,6 +205,7 @@ add_task(async function test_network_markers_service_worker_register() {
|
|||
};
|
||||
|
||||
Assert.objectContains(parentMarker, expectedProperties);
|
||||
Assert.objectContains(serviceWorkerMarker, expectedProperties);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -178,6 +178,10 @@ add_task(async function test_network_markers_service_worker_use() {
|
|||
const contentStopMarkers = contentPairs.map(
|
||||
([_, stopMarker]) => stopMarker
|
||||
);
|
||||
const serviceWorkerStopMarkers = serviceWorkerPairs.map(
|
||||
([_, stopMarker]) => stopMarker
|
||||
);
|
||||
|
||||
// In this test we have very different results in the various threads, so
|
||||
// we'll assert every case separately.
|
||||
// A simple function to help constructing better assertions:
|
||||
|
@ -390,7 +394,11 @@ add_task(async function test_network_markers_service_worker_use() {
|
|||
// The "1" requests are the initial requests that are intercepted, coming
|
||||
// from the web page, while the "2" requests are the requests coming from
|
||||
// the service worker.
|
||||
let htmlFetch1, generatedSvgFetch1, firefoxSvgFetch1;
|
||||
let htmlFetch1,
|
||||
htmlFetch2,
|
||||
generatedSvgFetch1,
|
||||
firefoxSvgFetch1,
|
||||
firefoxSvgFetch2;
|
||||
|
||||
// First, let's handle the case where the threads are different:
|
||||
if (serviceWorkerParentThread !== contentThread) {
|
||||
|
@ -410,6 +418,18 @@ add_task(async function test_network_markers_service_worker_use() {
|
|||
);
|
||||
|
||||
[htmlFetch1, generatedSvgFetch1, firefoxSvgFetch1] = contentStopMarkers;
|
||||
|
||||
// In the service worker parent thread, we have 2 network markers:
|
||||
// - the HTML file
|
||||
// - the firefox SVG file.
|
||||
// Remember that the generated SVG file is returned directly by the SW.
|
||||
Assert.equal(
|
||||
serviceWorkerStopMarkers.length,
|
||||
2,
|
||||
"There should be 2 stop markers in the service worker thread."
|
||||
);
|
||||
|
||||
[htmlFetch2, firefoxSvgFetch2] = serviceWorkerStopMarkers;
|
||||
} else {
|
||||
// Else case: the service worker parent thread IS the content thread
|
||||
// (note: this is always the case with fission). In that case all network
|
||||
|
@ -428,9 +448,11 @@ add_task(async function test_network_markers_service_worker_use() {
|
|||
// everything happens first in the main process, possibly before a
|
||||
// content process even exists, and the content process is merely
|
||||
// notified at the end.
|
||||
htmlFetch2,
|
||||
htmlFetch1,
|
||||
generatedSvgFetch1,
|
||||
firefoxSvgFetch1,
|
||||
firefoxSvgFetch2,
|
||||
] = contentStopMarkers;
|
||||
}
|
||||
|
||||
|
@ -479,5 +501,58 @@ add_task(async function test_network_markers_service_worker_use() {
|
|||
innerWindowID: Expect.number(),
|
||||
}),
|
||||
});
|
||||
|
||||
// Now let's test the markers coming from the service worker.
|
||||
Assert.objectContains(htmlFetch2, {
|
||||
name: Expect.stringMatches(/Load \d+:.*serviceworker_simple.html/),
|
||||
data: Expect.objectContainsOnly({
|
||||
type: "Network",
|
||||
status: "STATUS_STOP",
|
||||
URI: fullUrl("serviceworker_simple.html"),
|
||||
requestMethod: "GET",
|
||||
contentType: "text/html",
|
||||
startTime: Expect.number(),
|
||||
endTime: Expect.number(),
|
||||
domainLookupStart: Expect.number(),
|
||||
domainLookupEnd: Expect.number(),
|
||||
connectStart: Expect.number(),
|
||||
tcpConnectEnd: Expect.number(),
|
||||
connectEnd: Expect.number(),
|
||||
requestStart: Expect.number(),
|
||||
responseStart: Expect.number(),
|
||||
responseEnd: Expect.number(),
|
||||
id: Expect.number(),
|
||||
count: Expect.number(),
|
||||
pri: Expect.number(),
|
||||
// Note: no innerWindowID here, is that a bug?
|
||||
// Note: no cache either, this is bug 1544821.
|
||||
}),
|
||||
});
|
||||
|
||||
Assert.objectContains(firefoxSvgFetch2, {
|
||||
name: Expect.stringMatches(/Load \d+:.*firefox-logo-nightly.svg/),
|
||||
data: Expect.objectContainsOnly({
|
||||
type: "Network",
|
||||
status: "STATUS_STOP",
|
||||
URI: fullUrl("firefox-logo-nightly.svg"),
|
||||
requestMethod: "GET",
|
||||
contentType: "image/svg+xml",
|
||||
startTime: Expect.number(),
|
||||
endTime: Expect.number(),
|
||||
domainLookupStart: Expect.number(),
|
||||
domainLookupEnd: Expect.number(),
|
||||
connectStart: Expect.number(),
|
||||
tcpConnectEnd: Expect.number(),
|
||||
connectEnd: Expect.number(),
|
||||
requestStart: Expect.number(),
|
||||
responseStart: Expect.number(),
|
||||
responseEnd: Expect.number(),
|
||||
id: Expect.number(),
|
||||
count: Expect.number(),
|
||||
pri: Expect.number(),
|
||||
// Note: no innerWindowID here, is that a bug?
|
||||
// Note: no cache either, this is bug 1544821.
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче