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:
Butkovits Atila 2023-01-12 20:20:14 +02:00
Родитель 255bd963bc
Коммит 7855df7caf
32 изменённых файлов: 203 добавлений и 1418 удалений

Просмотреть файл

@ -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.
}),
});
});
});