diff --git a/dom/serviceworkers/ServiceWorkerPrivate.cpp b/dom/serviceworkers/ServiceWorkerPrivate.cpp index dc649f3aab8a..e123ee758141 100644 --- a/dom/serviceworkers/ServiceWorkerPrivate.cpp +++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp @@ -582,6 +582,8 @@ nsresult ServiceWorkerPrivate::Initialize() { mRemoteWorkerData = RemoteWorkerData( NS_ConvertUTF8toUTF16(mInfo->ScriptSpec()), baseScriptURL, baseScriptURL, /* name */ VoidString(), + /* workerType */ WorkerType::Classic, + /* credentials */ RequestCredentials::Omit, /* loading principal */ principalInfo, principalInfo, partitionedPrincipalInfo, /* useRegularPrincipal */ true, diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index 83cc7f2cc4e8..016adbb06027 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -259,19 +259,26 @@ void LoadAllScripts(WorkerPrivate* aWorkerPrivate, class ChannelGetterRunnable final : public WorkerMainThreadRunnable { const nsAString& mScriptURL; + const WorkerType& mWorkerType; + const RequestCredentials& mCredentials; const ClientInfo mClientInfo; WorkerLoadInfo& mLoadInfo; nsresult mResult; public: ChannelGetterRunnable(WorkerPrivate* aParentWorker, - const nsAString& aScriptURL, WorkerLoadInfo& aLoadInfo) + const nsAString& aScriptURL, + const WorkerType& aWorkerType, + const RequestCredentials& aCredentials, + WorkerLoadInfo& aLoadInfo) : WorkerMainThreadRunnable(aParentWorker, "ScriptLoader :: ChannelGetter"_ns), mScriptURL(aScriptURL) // ClientInfo should always be present since this should not be called // if parent's status is greater than Running. , + mWorkerType(aWorkerType), + mCredentials(aCredentials), mClientInfo(aParentWorker->GlobalScope()->GetClientInfo().ref()), mLoadInfo(aLoadInfo), mResult(NS_ERROR_FAILURE) { @@ -318,7 +325,7 @@ class ChannelGetterRunnable final : public WorkerMainThreadRunnable { mResult = workerinternals::ChannelFromScriptURLMainThread( mLoadInfo.mLoadingPrincipal, parentDoc, mLoadInfo.mLoadGroup, url, - clientInfo, + mWorkerType, mCredentials, clientInfo, // Nested workers are always dedicated. nsIContentPolicy::TYPE_INTERNAL_WORKER, mLoadInfo.mCookieJarSettings, mLoadInfo.mReferrerInfo, getter_AddRefs(channel)); @@ -366,19 +373,24 @@ nsresult GetCommonSecFlags(bool aIsMainScript, nsIURI* uri, secFlags |= nsILoadInfo::SEC_ALLOW_CHROME; } + // Note: this is for backwards compatibility and goes against spec. + // We should find a better solution. + if (aIsMainScript && isData) { + secFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL; + } + return NS_OK; } -nsresult GetModuleSecFlags(nsIPrincipal* principal, - WorkerScriptType aWorkerScriptType, - ScriptLoadRequest* aRequest, +nsresult GetModuleSecFlags(bool aIsTopLevel, nsIPrincipal* principal, + WorkerScriptType aWorkerScriptType, nsIURI* aURI, RequestCredentials aCredentials, uint32_t& secFlags) { // Implements "To fetch a single module script," // Step 9. If destination is "worker", "sharedworker", or "serviceworker", // and the top-level module fetch flag is set, then set request's // mode to "same-origin". - secFlags = aRequest->GetWorkerLoadContext()->IsTopLevel() + secFlags = aIsTopLevel ? nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED : nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT; @@ -394,8 +406,7 @@ nsresult GetModuleSecFlags(nsIPrincipal* principal, secFlags |= nsILoadInfo::nsILoadInfo::SEC_COOKIES_OMIT; } - return GetCommonSecFlags(aRequest->GetWorkerLoadContext()->IsTopLevel(), - aRequest->mURI, principal, aWorkerScriptType, + return GetCommonSecFlags(aIsTopLevel, aURI, principal, aWorkerScriptType, secFlags); } @@ -407,16 +418,8 @@ nsresult GetClassicSecFlags(bool aIsMainScript, nsIURI* uri, ? nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED : nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT; - nsresult rv = GetCommonSecFlags(aIsMainScript, uri, principal, - aWorkerScriptType, secFlags); - bool isData = uri->SchemeIs("data"); - // Note: this is for backwards compatibility and goes against spec. - // We should find a better solution. - if (aIsMainScript && isData) { - secFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL; - } - - return rv; + return GetCommonSecFlags(aIsMainScript, uri, principal, aWorkerScriptType, + secFlags); } } // anonymous namespace @@ -906,9 +909,9 @@ nsresult WorkerScriptLoader::LoadScript( if (request->IsModuleRequest()) { referrerInfo = new ReferrerInfo(request->mReferrer, request->ReferrerPolicy()); - rv = GetModuleSecFlags(principal, mWorkerScriptType, request, - mWorkerRef->Private()->WorkerCredentials(), - secFlags); + rv = GetModuleSecFlags( + loadContext->IsTopLevel(), principal, mWorkerScriptType, + request->mURI, mWorkerRef->Private()->WorkerCredentials(), secFlags); } else { referrerInfo = ReferrerInfo::CreateForFetch(principal, nullptr); if (parentWorker && !loadContext->IsTopLevel()) { @@ -1574,7 +1577,9 @@ nsresult ScriptExecutorRunnable::Cancel() { nsresult ChannelFromScriptURLMainThread( nsIPrincipal* aPrincipal, Document* aParentDoc, nsILoadGroup* aLoadGroup, - nsIURI* aScriptURL, const Maybe& aClientInfo, + nsIURI* aScriptURL, const WorkerType& aWorkerType, + const RequestCredentials& aCredentials, + const Maybe& aClientInfo, nsContentPolicyType aMainScriptContentPolicyType, nsICookieJarSettings* aCookieJarSettings, nsIReferrerInfo* aReferrerInfo, nsIChannel** aChannel) { @@ -1586,8 +1591,14 @@ nsresult ChannelFromScriptURLMainThread( NS_ASSERTION(secMan, "This should never be null!"); uint32_t secFlags; - nsresult rv = - GetClassicSecFlags(true, aScriptURL, aPrincipal, WorkerScript, secFlags); + nsresult rv; + if (aWorkerType == WorkerType::Module) { + rv = GetModuleSecFlags(true, aPrincipal, WorkerScript, aScriptURL, + aCredentials, secFlags); + } else { + rv = GetClassicSecFlags(true, aScriptURL, aPrincipal, WorkerScript, + secFlags); + } if (NS_FAILED(rv)) { return rv; } @@ -1599,14 +1610,14 @@ nsresult ChannelFromScriptURLMainThread( aCookieJarSettings, aReferrerInfo, aChannel); } -nsresult ChannelFromScriptURLWorkerThread(JSContext* aCx, - WorkerPrivate* aParent, - const nsAString& aScriptURL, - WorkerLoadInfo& aLoadInfo) { +nsresult ChannelFromScriptURLWorkerThread( + JSContext* aCx, WorkerPrivate* aParent, const nsAString& aScriptURL, + const WorkerType& aWorkerType, const RequestCredentials& aCredentials, + WorkerLoadInfo& aLoadInfo) { aParent->AssertIsOnWorkerThread(); - RefPtr getter = - new ChannelGetterRunnable(aParent, aScriptURL, aLoadInfo); + RefPtr getter = new ChannelGetterRunnable( + aParent, aScriptURL, aWorkerType, aCredentials, aLoadInfo); ErrorResult rv; getter->Dispatch(Canceling, rv); diff --git a/dom/workers/ScriptLoader.h b/dom/workers/ScriptLoader.h index ecc43be442e9..810029a33804 100644 --- a/dom/workers/ScriptLoader.h +++ b/dom/workers/ScriptLoader.h @@ -10,6 +10,7 @@ #include "js/loader/ScriptLoadRequest.h" #include "js/loader/ModuleLoadRequest.h" #include "js/loader/ModuleLoaderBase.h" +#include "mozilla/dom/WorkerBinding.h" #include "mozilla/dom/WorkerCommon.h" #include "mozilla/dom/WorkerLoadContext.h" #include "mozilla/dom/WorkerRef.h" @@ -327,15 +328,17 @@ class ScriptLoaderRunnable final : public nsIRunnable, public nsINamed { nsresult ChannelFromScriptURLMainThread( nsIPrincipal* aPrincipal, Document* aParentDoc, nsILoadGroup* aLoadGroup, - nsIURI* aScriptURL, const Maybe& aClientInfo, + nsIURI* aScriptURL, const WorkerType& aWorkerType, + const RequestCredentials& aCredentials, + const Maybe& aClientInfo, nsContentPolicyType aContentPolicyType, nsICookieJarSettings* aCookieJarSettings, nsIReferrerInfo* aReferrerInfo, nsIChannel** aChannel); -nsresult ChannelFromScriptURLWorkerThread(JSContext* aCx, - WorkerPrivate* aParent, - const nsAString& aScriptURL, - WorkerLoadInfo& aLoadInfo); +nsresult ChannelFromScriptURLWorkerThread( + JSContext* aCx, WorkerPrivate* aParent, const nsAString& aScriptURL, + const WorkerType& aWorkerType, const RequestCredentials& aCredentials, + WorkerLoadInfo& aLoadInfo); void ReportLoadError(ErrorResult& aRv, nsresult aLoadResult, const nsAString& aScriptURL); diff --git a/dom/workers/WorkerIPCUtils.h b/dom/workers/WorkerIPCUtils.h new file mode 100644 index 000000000000..0be45b307f9d --- /dev/null +++ b/dom/workers/WorkerIPCUtils.h @@ -0,0 +1,26 @@ +/* -*- 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/. */ +#ifndef _mozilla_dom_WorkerIPCUtils_h +#define _mozilla_dom_WorkerIPCUtils_h + +#include "ipc/EnumSerializer.h" + +// Undo X11/X.h's definition of None +#undef None + +#include "mozilla/dom/WorkerBinding.h" + +namespace IPC { + +template <> +struct ParamTraits + : public ContiguousEnumSerializer {}; + +} // namespace IPC + +#endif // _mozilla_dom_WorkerIPCUtils_h diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 835017a4d681..5d4c8f80af0b 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -2590,9 +2590,9 @@ already_AddRefed WorkerPrivate::Constructor( if (!aLoadInfo) { stackLoadInfo.emplace(); - nsresult rv = - GetLoadInfo(aCx, nullptr, parent, aScriptURL, aIsChromeWorker, - InheritLoadGroup, aWorkerKind, stackLoadInfo.ptr()); + nsresult rv = GetLoadInfo( + aCx, nullptr, parent, aScriptURL, aWorkerType, aRequestCredentials, + aIsChromeWorker, InheritLoadGroup, aWorkerKind, stackLoadInfo.ptr()); aRv.MightThrowJSException(); if (NS_FAILED(rv)) { workerinternals::ReportLoadError(aRv, rv, aScriptURL); @@ -2714,13 +2714,12 @@ nsresult WorkerPrivate::SetIsDebuggerReady(bool aReady) { } // static -nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, - WorkerPrivate* aParent, - const nsAString& aScriptURL, - bool aIsChromeWorker, - LoadGroupBehavior aLoadGroupBehavior, - WorkerKind aWorkerKind, - WorkerLoadInfo* aLoadInfo) { +nsresult WorkerPrivate::GetLoadInfo( + JSContext* aCx, nsPIDOMWindowInner* aWindow, WorkerPrivate* aParent, + const nsAString& aScriptURL, const enum WorkerType& aWorkerType, + const RequestCredentials& aCredentials, bool aIsChromeWorker, + LoadGroupBehavior aLoadGroupBehavior, WorkerKind aWorkerKind, + WorkerLoadInfo* aLoadInfo) { using namespace mozilla::dom::workerinternals; MOZ_ASSERT(aCx); @@ -2750,7 +2749,8 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, // Passing a pointer to our stack loadInfo is safe here because this // method uses a sync runnable to get the channel from the main thread. - rv = ChannelFromScriptURLWorkerThread(aCx, aParent, aScriptURL, loadInfo); + rv = ChannelFromScriptURLWorkerThread(aCx, aParent, aScriptURL, aWorkerType, + aCredentials, loadInfo); if (NS_FAILED(rv)) { MOZ_ALWAYS_TRUE(loadInfo.ProxyReleaseMainThreadObjects(aParent)); return rv; @@ -3022,8 +3022,9 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, rv = ChannelFromScriptURLMainThread( loadInfo.mLoadingPrincipal, document, loadInfo.mLoadGroup, url, - clientInfo, ContentPolicyType(aWorkerKind), loadInfo.mCookieJarSettings, - loadInfo.mReferrerInfo, getter_AddRefs(loadInfo.mChannel)); + aWorkerType, aCredentials, clientInfo, ContentPolicyType(aWorkerKind), + loadInfo.mCookieJarSettings, loadInfo.mReferrerInfo, + getter_AddRefs(loadInfo.mChannel)); NS_ENSURE_SUCCESS(rv, rv); rv = NS_GetFinalChannelURI(loadInfo.mChannel, diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index a3d28933a02e..2baf0def89ab 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -159,12 +159,12 @@ class WorkerPrivate final enum LoadGroupBehavior { InheritLoadGroup, OverrideLoadGroup }; - static nsresult GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, - WorkerPrivate* aParent, - const nsAString& aScriptURL, bool aIsChromeWorker, - LoadGroupBehavior aLoadGroupBehavior, - WorkerKind aWorkerKind, - WorkerLoadInfo* aLoadInfo); + static nsresult GetLoadInfo( + JSContext* aCx, nsPIDOMWindowInner* aWindow, WorkerPrivate* aParent, + const nsAString& aScriptURL, const enum WorkerType& aWorkerType, + const RequestCredentials& aCredentials, bool aIsChromeWorker, + LoadGroupBehavior aLoadGroupBehavior, WorkerKind aWorkerKind, + WorkerLoadInfo* aLoadInfo); void Traverse(nsCycleCollectionTraversalCallback& aCb); diff --git a/dom/workers/moz.build b/dom/workers/moz.build index b2f9fd803ad6..5686130c4289 100644 --- a/dom/workers/moz.build +++ b/dom/workers/moz.build @@ -19,6 +19,7 @@ EXPORTS.mozilla.dom += [ "WorkerDebuggerManager.h", "WorkerDocumentListener.h", "WorkerError.h", + "WorkerIPCUtils.h", "WorkerLoadInfo.h", "WorkerLocation.h", "WorkerNavigator.h", diff --git a/dom/workers/remoteworkers/RemoteWorkerChild.cpp b/dom/workers/remoteworkers/RemoteWorkerChild.cpp index 64cf434fb44f..09616b3bce45 100644 --- a/dom/workers/remoteworkers/RemoteWorkerChild.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerChild.cpp @@ -435,7 +435,7 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread(RemoteWorkerData&& aData) { // uri encoding. rv = ChannelFromScriptURLMainThread( info.mLoadingPrincipal, nullptr /* parent document */, info.mLoadGroup, - info.mResolvedScriptURI, clientInfo, + info.mResolvedScriptURI, aData.type(), aData.credentials(), clientInfo, nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER, info.mCookieJarSettings, info.mReferrerInfo, getter_AddRefs(info.mChannel)); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -451,8 +451,9 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread(RemoteWorkerData&& aData) { ErrorResult error; RefPtr workerPrivate = WorkerPrivate::Constructor( jsapi.cx(), aData.originalScriptURL(), false, - mIsServiceWorker ? WorkerKindService : WorkerKindShared, aData.name(), - VoidCString(), &info, error, std::move(workerPrivateId)); + mIsServiceWorker ? WorkerKindService : WorkerKindShared, + aData.credentials(), aData.type(), aData.name(), VoidCString(), &info, + error, std::move(workerPrivateId)); if (NS_WARN_IF(error.Failed())) { MOZ_ASSERT(!workerPrivate); diff --git a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh index cde177197021..4cf0862c27b0 100644 --- a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh +++ b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh @@ -13,10 +13,13 @@ include ProtocolTypes; include "mozilla/dom/ClientIPCUtils.h"; include "mozilla/dom/ReferrerInfoUtils.h"; +include "mozilla/dom/WorkerIPCUtils.h"; using struct mozilla::void_t from "mozilla/ipc/IPCCore.h"; +using mozilla::dom::RequestCredentials from "mozilla/dom/RequestBinding.h"; using mozilla::StorageAccess from "mozilla/StorageAccess.h"; using mozilla::OriginTrials from "mozilla/OriginTrialsIPCUtils.h"; +using mozilla::dom::WorkerType from "mozilla/dom/WorkerBinding.h"; namespace mozilla { namespace dom { @@ -51,6 +54,8 @@ struct RemoteWorkerData URIParams resolvedScriptURL; nsString name; + WorkerType type; + RequestCredentials credentials; PrincipalInfo loadingPrincipalInfo; PrincipalInfo principalInfo; diff --git a/dom/workers/sharedworkers/SharedWorker.cpp b/dom/workers/sharedworkers/SharedWorker.cpp index d068f7c3bdd2..b5aa7d9e2ee2 100644 --- a/dom/workers/sharedworkers/SharedWorker.cpp +++ b/dom/workers/sharedworkers/SharedWorker.cpp @@ -107,19 +107,23 @@ already_AddRefed SharedWorker::Constructor( #endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED nsAutoString name; + WorkerType workerType = WorkerType::Classic; + RequestCredentials credentials = RequestCredentials::Omit; if (aOptions.IsString()) { name = aOptions.GetAsString(); } else { MOZ_ASSERT(aOptions.IsWorkerOptions()); name = aOptions.GetAsWorkerOptions().mName; + workerType = aOptions.GetAsWorkerOptions().mType; + credentials = aOptions.GetAsWorkerOptions().mCredentials; } JSContext* cx = aGlobal.Context(); WorkerLoadInfo loadInfo; - aRv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, aScriptURL, false, - WorkerPrivate::OverrideLoadGroup, - WorkerKindShared, &loadInfo); + aRv = WorkerPrivate::GetLoadInfo( + cx, window, nullptr, aScriptURL, workerType, credentials, false, + WorkerPrivate::OverrideLoadGroup, WorkerKindShared, &loadInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } @@ -229,9 +233,9 @@ already_AddRefed SharedWorker::Constructor( } RemoteWorkerData remoteWorkerData( - nsString(aScriptURL), baseURL, resolvedScriptURL, name, - loadingPrincipalInfo, principalInfo, partitionedPrincipalInfo, - loadInfo.mUseRegularPrincipal, + nsString(aScriptURL), baseURL, resolvedScriptURL, name, workerType, + credentials, loadingPrincipalInfo, principalInfo, + partitionedPrincipalInfo, loadInfo.mUseRegularPrincipal, loadInfo.mHasStorageAccessPermissionGranted, cjsData, loadInfo.mDomain, isSecureContext, ipcClientInfo, loadInfo.mReferrerInfo, storageAllowed, AntiTrackingUtils::IsThirdPartyWindow(window, nullptr),