/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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"WorkletFetchHandler.h"
using JS::loader::ModuleLoadRequest; using JS::loader::ParserMetadata; using JS::loader::ScriptFetchOptions; using mozilla::dom::loader::WorkletModuleLoader;
namespace mozilla::dom {
// A Runnable to call ModuleLoadRequest::StartModuleLoad on a worklet thread. class StartModuleLoadRunnable final : public Runnable { public:
StartModuleLoadRunnable(
WorkletImpl* aWorkletImpl, const nsMainThreadPtrHandle<WorkletFetchHandler>& aHandlerRef,
nsCOMPtr<nsIURI> aURI, nsIURI* aReferrer, const nsTArray<nsString>& aLocalizedStrs)
: Runnable("Worklet::StartModuleLoadRunnable"),
mWorkletImpl(aWorkletImpl),
mHandlerRef(aHandlerRef),
mURI(std::move(aURI)),
mReferrer(aReferrer),
mLocalizedStrs(aLocalizedStrs),
mParentRuntime(
JS_GetParentRuntime(CycleCollectedJSContext::Get()->Context())) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mParentRuntime);
xpc::SetPrefableContextOptions(mContextOptions);
}
NS_IMETHODIMP
StartModuleLoadRunnable::Run() { // WorkletThread::IsOnWorkletThread() cannot be used here because it depends // on a WorkletJSContext having been created for this thread. That does not // happen until the global scope is created the first time // RunOnWorkletThread() is called.
MOZ_ASSERT(!NS_IsMainThread()); return RunOnWorkletThread();
}
NS_IMETHODIMP StartModuleLoadRunnable::RunOnWorkletThread() { // This can be called on a GraphRunner thread or a DOM Worklet thread.
WorkletThread::EnsureCycleCollectedJSContext(mParentRuntime, mContextOptions);
WorkletGlobalScope* globalScope = mWorkletImpl->GetGlobalScope(); if (!globalScope) { return NS_ERROR_DOM_UNKNOWN_ERR;
}
// To fetch a worklet/module worker script graph: // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-worklet/module-worker-script-graph // Step 1. Let options be a script fetch options whose cryptographic nonce is // the empty string, integrity metadata is the empty string, parser metadata // is "not-parser-inserted", credentials mode is credentials mode, referrer // policy is the empty string, and fetch priority is "auto".
RefPtr<ScriptFetchOptions> fetchOptions = new ScriptFetchOptions(
CORSMode::CORS_NONE, /* aNonce = */ u""_ns, RequestPriority::Auto,
ParserMetadata::NotParserInserted, /*triggeringPrincipal*/ nullptr);
// Part of Step 2. This sets the Top-level flag to true
RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest(
mURI, JS::ModuleType::JavaScript, ReferrerPolicy::_empty, fetchOptions,
SRIMetadata(), mReferrer, loadContext, true, /* is top level */ false, /* is dynamic import */
moduleLoader, visitedSet, nullptr);
nsCOMPtr<nsIURI> resolvedURI;
nsresult rv = NS_NewURI(getter_AddRefs(resolvedURI), aModuleURL, nullptr,
doc->GetBaseURI()); if (NS_WARN_IF(NS_FAILED(rv))) { // https://html.spec.whatwg.org/multipage/worklets.html#dom-worklet-addmodule // Step 3. If this fails, then return a promise rejected with a // "SyntaxError" DOMException.
rv = NS_ERROR_DOM_SYNTAX_ERR;
// Maybe we already have an handler for this URI
{
WorkletFetchHandler* handler = aWorklet->GetImportFetchHandler(spec); if (handler) {
handler->AddPromise(aCx, promise); return promise.forget();
}
}
RefPtr<WorkletFetchHandler> handler = new WorkletFetchHandler(aWorklet, promise, aOptions.mCredentials);
nsMainThreadPtrHandle<WorkletFetchHandler> handlerRef{ new nsMainThreadPtrHolder<WorkletFetchHandler>("FetchHandler", handler)};
// Determine request's Referrer // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer // Step 3. Switch on request’s referrer: // "client" // Step 1.4. Let referrerSource be document’s URL.
nsIURI* referrer = doc->GetDocumentURIAsReferrer();
nsCOMPtr<nsIRunnable> runnable = new StartModuleLoadRunnable(
aWorklet->mImpl, handlerRef, std::move(resolvedURI), referrer,
aWorklet->GetLocalizedStrings());
if (NS_FAILED(aWorklet->mImpl->SendControlMessage(runnable.forget()))) { return nullptr;
}
if (aReferrer) {
res = aReferrer->GetSpec(requestInit.mReferrer.Construct()); if (NS_WARN_IF(NS_FAILED(res))) { return NS_ERROR_FAILURE;
}
}
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(mWorklet->GetParentObject());
MOZ_ASSERT(global);
// Note: added to infer a default credentials mode in the Request setup, // but we always pass an explicit credentials value in requestInit, so // this has no effect right now. Bug 1887862 covers fixing worklets to behave // the same as "normal" fetch calls.
nsIPrincipal* p = global->PrincipalOrNull();
CallerType callerType = (p && p->IsSystemPrincipal() ? CallerType::System
: CallerType::NonSystem);
IgnoredErrorResult rv;
SafeRefPtr<Request> request = Request::Constructor(
global, aCx, requestInput, requestInit, callerType, rv); if (rv.Failed()) { return NS_ERROR_FAILURE;
}
if (NS_WARN_IF(
NS_FAILED(mWorklet->mImpl->SendControlMessage(runnable.forget())))) {
NS_WARNING("Failed to dispatch FetchCompleteRunnable to a worklet thread.");
}
}
if (NS_FAILED(aStatus)) {
HandleFailure(aStatus); return NS_OK;
}
// Copy the buffer and decode it on worklet thread, as we can only access // ModuleLoadRequest on worklet thread.
UniquePtr<uint8_t[]> scriptTextBuf = MakeUnique<uint8_t[]>(aStringLen);
memcpy(scriptTextBuf.get(), aString, aStringLen);
nsCOMPtr<nsIRunnable> runnable = new FetchCompleteRunnable(
mWorklet->mImpl, mURI, NS_OK, std::move(scriptTextBuf), aStringLen);
if (NS_FAILED(mWorklet->mImpl->SendControlMessage(runnable.forget()))) {
HandleFailure(NS_ERROR_FAILURE);
}
if (NS_WARN_IF(
NS_FAILED(mWorklet->mImpl->SendControlMessage(runnable.forget())))) {
NS_WARNING("Failed to dispatch FetchCompleteRunnable to a worklet thread.");
}
}
} // namespace mozilla::dom
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.