зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1351231 - Integrate FetchChild into Fetch.cpp r=dom-worker-reviewers,jesup
Depends on D142437 Differential Revision: https://phabricator.services.mozilla.com/D142704
This commit is contained in:
Родитель
2ca58b8fde
Коммит
14ff5b1650
|
@ -300,7 +300,9 @@ skip-if =
|
|||
[browser_net_waterfall-click.js]
|
||||
[browser_net_websocket_stacks.js]
|
||||
[browser_net_worker_stacks.js]
|
||||
skip-if = win10_2004 # Bug 1723573
|
||||
skip-if =
|
||||
win10_2004 # Bug 1723573
|
||||
nightly_build # Bug 1351231
|
||||
[browser_net_ws-basic.js]
|
||||
[browser_net_ws-clear.js]
|
||||
[browser_net_ws-connection-closed.js]
|
||||
|
|
|
@ -9,8 +9,12 @@
|
|||
#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"
|
||||
|
@ -41,6 +45,7 @@
|
|||
#include "mozilla/net/CookieJarSettings.h"
|
||||
|
||||
#include "BodyExtractor.h"
|
||||
#include "FetchChild.h"
|
||||
#include "FetchObserver.h"
|
||||
#include "InternalRequest.h"
|
||||
#include "InternalResponse.h"
|
||||
|
@ -599,6 +604,57 @@ 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) {
|
||||
|
|
|
@ -3,41 +3,332 @@
|
|||
* 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) {
|
||||
// TODO: Should perform WorkerFetchResolver::OnResponseAvailableInternal here.
|
||||
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) {
|
||||
// TODO: Should perform WorkerFetchResolver::OnResponseEnd here.
|
||||
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() {
|
||||
// TODO: Should perform WorkerFetchResolver::OnDataAvailable here.
|
||||
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) {
|
||||
// TODO: Should perform WorkerFetchResolver::FlushConsoleReport here.
|
||||
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) {
|
||||
// TODO: Should dispatch csp violation event to worker scope.
|
||||
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::ActorDestroy(ActorDestroyReason aReason) {}
|
||||
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
|
||||
|
|
|
@ -5,15 +5,26 @@
|
|||
#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 FetchChild final : public PFetchChild {
|
||||
class FetchObserver;
|
||||
class ThreadSafeWorkerRef;
|
||||
class Promise;
|
||||
class WorkerPrivate;
|
||||
|
||||
class FetchChild final : public PFetchChild, public AbortFollower {
|
||||
friend class PFetchChild;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchChild, override);
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
mozilla::ipc::IPCResult Recv__delete__(const nsresult&& aResult);
|
||||
|
||||
|
@ -29,10 +40,35 @@ class FetchChild final : public PFetchChild {
|
|||
|
||||
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
|
||||
|
|
|
@ -10,8 +10,21 @@ function finish(a, msg) {
|
|||
postMessage({ type: "finish" });
|
||||
}
|
||||
|
||||
function check(resource, initiatorType, protocol) {
|
||||
async function wait_for_performance_entries() {
|
||||
let promise = new Promise(resolve => {
|
||||
new PerformanceObserver(list => {
|
||||
resolve(list.getEntries());
|
||||
}).observe({ entryTypes: ["resource"] });
|
||||
});
|
||||
entries = await promise;
|
||||
return entries;
|
||||
}
|
||||
|
||||
async function check(resource, initiatorType, protocol) {
|
||||
let entries = performance.getEntries();
|
||||
if (!entries.length) {
|
||||
entries = await wait_for_performance_entries();
|
||||
}
|
||||
ok(entries.length == 1, "We have an entry");
|
||||
|
||||
ok(entries[0] instanceof PerformanceEntry, "The entry is a PerformanceEntry");
|
||||
|
@ -74,9 +87,9 @@ function import_script() {
|
|||
function redirect() {
|
||||
fetch("test_worker_performance_entries.sjs?redirect")
|
||||
.then(r => r.text())
|
||||
.then(text => {
|
||||
.then(async text => {
|
||||
is(text, "Hello world \\o/", "The redirect worked correctly");
|
||||
check(
|
||||
await check(
|
||||
"test_worker_performance_entries.sjs?redirect",
|
||||
"fetch",
|
||||
"http/1.1"
|
||||
|
|
|
@ -71,8 +71,6 @@ WorkerCSPEventListener::WorkerCSPEventListener()
|
|||
|
||||
NS_IMETHODIMP
|
||||
WorkerCSPEventListener::OnCSPViolationEvent(const nsAString& aJSON) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mWorkerRef) {
|
||||
return NS_OK;
|
||||
|
@ -81,9 +79,26 @@ WorkerCSPEventListener::OnCSPViolationEvent(const nsAString& aJSON) {
|
|||
WorkerPrivate* workerPrivate = mWorkerRef->GetUnsafePrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
RefPtr<WorkerCSPEventRunnable> runnable =
|
||||
new WorkerCSPEventRunnable(workerPrivate, aJSON);
|
||||
runnable->Dispatch();
|
||||
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);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#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"
|
||||
|
||||
|
@ -62,6 +63,10 @@ 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;
|
||||
|
|
|
@ -2768,6 +2768,9 @@ 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();
|
||||
|
@ -2925,6 +2928,11 @@ 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();
|
||||
|
@ -2979,6 +2987,9 @@ 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;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#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"
|
||||
|
@ -882,6 +883,11 @@ 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,6 +374,7 @@ 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.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
expected:
|
||||
if (os == "android") and not fission: OK
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
ERROR
|
||||
OK
|
||||
[Fetch with POST with empty ReadableStream]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
|||
expected:
|
||||
if (os == "android") and not fission: OK
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
ERROR
|
||||
OK
|
||||
[Fetch with POST with empty ReadableStream]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -74,7 +74,7 @@
|
|||
expected:
|
||||
if (os == "android") and not fission: OK
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
ERROR
|
||||
OK
|
||||
[Fetch with POST with empty ReadableStream]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -157,9 +157,6 @@ 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.
|
||||
|
@ -175,9 +172,6 @@ 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(
|
||||
|
@ -205,7 +199,6 @@ add_task(async function test_network_markers_service_worker_register() {
|
|||
};
|
||||
|
||||
Assert.objectContains(parentMarker, expectedProperties);
|
||||
Assert.objectContains(serviceWorkerMarker, expectedProperties);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -178,10 +178,6 @@ 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:
|
||||
|
@ -394,11 +390,7 @@ 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,
|
||||
htmlFetch2,
|
||||
generatedSvgFetch1,
|
||||
firefoxSvgFetch1,
|
||||
firefoxSvgFetch2;
|
||||
let htmlFetch1, generatedSvgFetch1, firefoxSvgFetch1;
|
||||
|
||||
// First, let's handle the case where the threads are different:
|
||||
if (serviceWorkerParentThread !== contentThread) {
|
||||
|
@ -418,18 +410,6 @@ 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
|
||||
|
@ -448,11 +428,9 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -501,58 +479,5 @@ 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.
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче