Bug 1148935 - Correctly reflect worker and sharedworker RequestContext values; r=smaug

This commit is contained in:
Ehsan Akhgari 2015-06-16 21:21:08 -04:00
parent cee6f01c68
commit f6c4133715
17 changed files with 153 additions and 16 deletions

View File

@ -214,7 +214,7 @@ nsScriptLoader::CheckContentPolicy(nsIDocument* aDocument,
const nsAString &aType) const nsAString &aType)
{ {
int16_t shouldLoad = nsIContentPolicy::ACCEPT; int16_t shouldLoad = nsIContentPolicy::ACCEPT;
nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT, nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_INTERNAL_SCRIPT,
aURI, aURI,
aDocument->NodePrincipal(), aDocument->NodePrincipal(),
aContext, aContext,
@ -289,7 +289,7 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType,
aRequest->mURI, aRequest->mURI,
mDocument, mDocument,
nsILoadInfo::SEC_NORMAL, nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_SCRIPT, nsIContentPolicy::TYPE_INTERNAL_SCRIPT,
loadGroup, loadGroup,
prompter, prompter,
nsIRequest::LOAD_NORMAL | nsIRequest::LOAD_NORMAL |

View File

@ -113,9 +113,15 @@ InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aConte
case nsIContentPolicy::TYPE_OTHER: case nsIContentPolicy::TYPE_OTHER:
context = RequestContext::Internal; context = RequestContext::Internal;
break; break;
case nsIContentPolicy::TYPE_SCRIPT: case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
context = RequestContext::Script; context = RequestContext::Script;
break; break;
case nsIContentPolicy::TYPE_INTERNAL_WORKER:
context = RequestContext::Worker;
break;
case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
context = RequestContext::Sharedworker;
break;
case nsIContentPolicy::TYPE_IMAGE: case nsIContentPolicy::TYPE_IMAGE:
context = RequestContext::Image; context = RequestContext::Image;
break; break;

View File

@ -53,13 +53,13 @@ namespace dom {
* ping | TYPE_PING * ping | TYPE_PING
* plugin | TYPE_OBJECT_SUBREQUEST * plugin | TYPE_OBJECT_SUBREQUEST
* prefetch | * prefetch |
* script | TYPE_SCRIPT * script | TYPE_INTERNAL_SCRIPT
* sharedworker | * sharedworker | TYPE_INTERNAL_SHARED_WORKER
* subresource | Not supported by Gecko * subresource | Not supported by Gecko
* style | TYPE_STYLESHEET * style | TYPE_STYLESHEET
* track | TYPE_INTERNAL_TRACK * track | TYPE_INTERNAL_TRACK
* video | TYPE_INTERNAL_VIDEO * video | TYPE_INTERNAL_VIDEO
* worker | * worker | TYPE_INTERNAL_WORKER
* xmlhttprequest | TYPE_XMLHTTPREQUEST * xmlhttprequest | TYPE_XMLHTTPREQUEST
* xslt | TYPE_XSLT * xslt | TYPE_XSLT
* *
@ -68,7 +68,6 @@ namespace dom {
* TODO: Split TYPE_XMLHTTPREQUEST and TYPE_DATAREQUEST for EventSource * TODO: Split TYPE_XMLHTTPREQUEST and TYPE_DATAREQUEST for EventSource
* TODO: Figure out if TYPE_WEBSOCKET maps to anything useful * TODO: Figure out if TYPE_WEBSOCKET maps to anything useful
* TODO: Differentiate between frame and iframe * TODO: Differentiate between frame and iframe
* TODO: Add content types for different kinds of workers
* TODO: Add a content type for prefetch * TODO: Add a content type for prefetch
* TODO: Use the content type for manifest when it becomes available * TODO: Use the content type for manifest when it becomes available
* TODO: Add a content type for location * TODO: Add a content type for location

View File

@ -2344,7 +2344,7 @@ RuntimeService::CreateSharedWorkerInternal(const GlobalObject& aGlobal,
nsresult rv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, aScriptURL, nsresult rv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, aScriptURL,
false, false,
WorkerPrivate::OverrideLoadGroup, WorkerPrivate::OverrideLoadGroup,
&loadInfo); aType, &loadInfo);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return CreateSharedWorkerFromLoadInfo(cx, &loadInfo, aScriptURL, aName, aType, return CreateSharedWorkerFromLoadInfo(cx, &loadInfo, aScriptURL, aName, aType,

View File

@ -95,6 +95,7 @@ ChannelFromScriptURL(nsIPrincipal* principal,
const nsAString& aScriptURL, const nsAString& aScriptURL,
bool aIsMainScript, bool aIsMainScript,
WorkerScriptType aWorkerScriptType, WorkerScriptType aWorkerScriptType,
nsContentPolicyType aContentPolicyType,
nsIChannel** aChannel) nsIChannel** aChannel)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
@ -111,7 +112,7 @@ ChannelFromScriptURL(nsIPrincipal* principal,
// If we're part of a document then check the content load policy. // If we're part of a document then check the content load policy.
if (parentDoc) { if (parentDoc) {
int16_t shouldLoad = nsIContentPolicy::ACCEPT; int16_t shouldLoad = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT, uri, rv = NS_CheckContentLoadPolicy(aContentPolicyType, uri,
principal, parentDoc, principal, parentDoc,
NS_LITERAL_CSTRING("text/javascript"), NS_LITERAL_CSTRING("text/javascript"),
nullptr, &shouldLoad, nullptr, &shouldLoad,
@ -166,7 +167,7 @@ ChannelFromScriptURL(nsIPrincipal* principal,
uri, uri,
parentDoc, parentDoc,
nsILoadInfo::SEC_NORMAL, nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_SCRIPT, aContentPolicyType,
loadGroup, loadGroup,
nullptr, // aCallbacks nullptr, // aCallbacks
flags, flags,
@ -181,7 +182,7 @@ ChannelFromScriptURL(nsIPrincipal* principal,
uri, uri,
principal, principal,
nsILoadInfo::SEC_NORMAL, nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_SCRIPT, aContentPolicyType,
loadGroup, loadGroup,
nullptr, // aCallbacks nullptr, // aCallbacks
flags, flags,
@ -807,7 +808,9 @@ private:
if (!channel) { if (!channel) {
rv = ChannelFromScriptURL(principal, baseURI, parentDoc, loadGroup, ios, rv = ChannelFromScriptURL(principal, baseURI, parentDoc, loadGroup, ios,
secMan, loadInfo.mURL, IsMainWorkerScript(), secMan, loadInfo.mURL, IsMainWorkerScript(),
mWorkerScriptType, getter_AddRefs(channel)); mWorkerScriptType,
mWorkerPrivate->ContentPolicyType(),
getter_AddRefs(channel));
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
@ -1519,6 +1522,8 @@ public:
scriptloader::ChannelFromScriptURLMainThread(principal, baseURI, scriptloader::ChannelFromScriptURLMainThread(principal, baseURI,
parentDoc, loadGroup, parentDoc, loadGroup,
mScriptURL, mScriptURL,
// Nested workers are always dedicated.
nsIContentPolicy::TYPE_INTERNAL_WORKER,
getter_AddRefs(channel)); getter_AddRefs(channel));
if (NS_SUCCEEDED(mResult)) { if (NS_SUCCEEDED(mResult)) {
channel.forget(mChannel); channel.forget(mChannel);
@ -1730,6 +1735,7 @@ ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal,
nsIDocument* aParentDoc, nsIDocument* aParentDoc,
nsILoadGroup* aLoadGroup, nsILoadGroup* aLoadGroup,
const nsAString& aScriptURL, const nsAString& aScriptURL,
nsContentPolicyType aContentPolicyType,
nsIChannel** aChannel) nsIChannel** aChannel)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
@ -1740,7 +1746,8 @@ ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal,
NS_ASSERTION(secMan, "This should never be null!"); NS_ASSERTION(secMan, "This should never be null!");
return ChannelFromScriptURL(aPrincipal, aBaseURI, aParentDoc, aLoadGroup, return ChannelFromScriptURL(aPrincipal, aBaseURI, aParentDoc, aLoadGroup,
ios, secMan, aScriptURL, true, WorkerScript, aChannel); ios, secMan, aScriptURL, true, WorkerScript,
aContentPolicyType, aChannel);
} }
nsresult nsresult

View File

@ -8,6 +8,7 @@
#define mozilla_dom_workers_scriptloader_h__ #define mozilla_dom_workers_scriptloader_h__
#include "Workers.h" #include "Workers.h"
#include "nsIContentPolicyBase.h"
class nsIPrincipal; class nsIPrincipal;
class nsIURI; class nsIURI;
@ -37,6 +38,7 @@ ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal,
nsIDocument* aParentDoc, nsIDocument* aParentDoc,
nsILoadGroup* aLoadGroup, nsILoadGroup* aLoadGroup,
const nsAString& aScriptURL, const nsAString& aScriptURL,
nsContentPolicyType aContentPolicyType,
nsIChannel** aChannel); nsIChannel** aChannel);
nsresult nsresult

View File

@ -2550,6 +2550,7 @@ ServiceWorkerManager::CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
NS_ConvertUTF8toUTF16(aInfo->ScriptSpec()), NS_ConvertUTF8toUTF16(aInfo->ScriptSpec()),
false, false,
WorkerPrivate::OverrideLoadGroup, WorkerPrivate::OverrideLoadGroup,
WorkerTypeService,
&loadInfo); &loadInfo);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;

View File

@ -88,10 +88,13 @@ public:
return rv; return rv;
} }
// Note that because there is no "serviceworker" RequestContext type, we can
// use the external TYPE_SCRIPT content policy types when loading a service
// worker.
rv = NS_NewChannel(getter_AddRefs(mChannel), rv = NS_NewChannel(getter_AddRefs(mChannel),
uri, aPrincipal, uri, aPrincipal,
nsILoadInfo::SEC_NORMAL, nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_SCRIPT); // FIXME(nsm): TYPE_SERVICEWORKER nsIContentPolicy::TYPE_SCRIPT);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }

View File

@ -4842,7 +4842,7 @@ WorkerPrivate::Constructor(JSContext* aCx,
nsresult rv = GetLoadInfo(aCx, nullptr, parent, aScriptURL, nsresult rv = GetLoadInfo(aCx, nullptr, parent, aScriptURL,
aIsChromeWorker, InheritLoadGroup, aIsChromeWorker, InheritLoadGroup,
stackLoadInfo.ptr()); aWorkerType, stackLoadInfo.ptr());
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
scriptloader::ReportLoadError(aCx, aScriptURL, rv, !parent); scriptloader::ReportLoadError(aCx, aScriptURL, rv, !parent);
aRv.Throw(rv); aRv.Throw(rv);
@ -4900,6 +4900,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
WorkerPrivate* aParent, const nsAString& aScriptURL, WorkerPrivate* aParent, const nsAString& aScriptURL,
bool aIsChromeWorker, bool aIsChromeWorker,
LoadGroupBehavior aLoadGroupBehavior, LoadGroupBehavior aLoadGroupBehavior,
WorkerType aWorkerType,
WorkerLoadInfo* aLoadInfo) WorkerLoadInfo* aLoadInfo)
{ {
using namespace mozilla::dom::workers::scriptloader; using namespace mozilla::dom::workers::scriptloader;
@ -5145,6 +5146,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
rv = ChannelFromScriptURLMainThread(loadInfo.mPrincipal, loadInfo.mBaseURI, rv = ChannelFromScriptURLMainThread(loadInfo.mPrincipal, loadInfo.mBaseURI,
document, loadInfo.mLoadGroup, document, loadInfo.mLoadGroup,
aScriptURL, aScriptURL,
ContentPolicyType(aWorkerType),
getter_AddRefs(loadInfo.mChannel)); getter_AddRefs(loadInfo.mChannel));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

View File

@ -9,6 +9,7 @@
#include "Workers.h" #include "Workers.h"
#include "nsIContentPolicy.h"
#include "nsIContentSecurityPolicy.h" #include "nsIContentSecurityPolicy.h"
#include "nsILoadGroup.h" #include "nsILoadGroup.h"
#include "nsIWorkerDebugger.h" #include "nsIWorkerDebugger.h"
@ -734,6 +735,27 @@ public:
return mWorkerType == WorkerTypeService; return mWorkerType == WorkerTypeService;
} }
nsContentPolicyType
ContentPolicyType() const
{
return ContentPolicyType(mWorkerType);
}
static nsContentPolicyType
ContentPolicyType(WorkerType aWorkerType)
{
switch (aWorkerType) {
case WorkerTypeDedicated:
return nsIContentPolicy::TYPE_INTERNAL_WORKER;
case WorkerTypeShared:
return nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER;
case WorkerTypeService:
return nsIContentPolicy::TYPE_SCRIPT;
default:
MOZ_ASSERT_UNREACHABLE("Invalid worker type");
}
}
const nsCString& const nsCString&
SharedWorkerName() const SharedWorkerName() const
{ {
@ -969,7 +991,8 @@ public:
static nsresult static nsresult
GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent, GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent,
const nsAString& aScriptURL, bool aIsChromeWorker, const nsAString& aScriptURL, bool aIsChromeWorker,
LoadGroupBehavior aLoadGroupBehavior, WorkerLoadInfo* aLoadInfo); LoadGroupBehavior aLoadGroupBehavior, WorkerType aWorkerType,
WorkerLoadInfo* aLoadInfo);
static void static void
OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo); OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo);

View File

@ -70,6 +70,22 @@ self.addEventListener("fetch", function(event) {
} }
} else if (event.request.url.indexOf("xslt") >= 0) { } else if (event.request.url.indexOf("xslt") >= 0) {
respondToServiceWorker(event, "xslt"); respondToServiceWorker(event, "xslt");
} else if (event.request.url.indexOf("myworker") >= 0) {
if (event.request.context == "worker") {
event.respondWith(fetch("worker.js"));
}
} else if (event.request.url.indexOf("myparentworker") >= 0) {
if (event.request.context == "worker") {
event.respondWith(fetch("parentworker.js"));
}
} else if (event.request.url.indexOf("mysharedworker") >= 0) {
if (event.request.context == "sharedworker") {
event.respondWith(fetch("sharedworker.js"));
}
} else if (event.request.url.indexOf("myparentsharedworker") >= 0) {
if (event.request.context == "sharedworker") {
event.respondWith(fetch("parentsharedworker.js"));
}
} else if (event.request.url.indexOf("cache") >= 0) { } else if (event.request.url.indexOf("cache") >= 0) {
var cache; var cache;
var origContext = event.request.context; var origContext = event.request.context;

View File

@ -341,6 +341,58 @@
}); });
} }
function testWorker() {
return new Promise(function(resolve, reject) {
var worker = new Worker("myworker");
worker.onmessage = function(e) {
if (e.data == "ack") {
worker.terminate();
resolve();
}
};
worker.onerror = reject;
});
}
function testNestedWorker() {
return new Promise(function(resolve, reject) {
var worker = new Worker("myparentworker");
worker.onmessage = function(e) {
if (e.data == "ack") {
worker.terminate();
resolve();
}
};
worker.onerror = reject;
});
}
function testSharedWorker() {
return new Promise(function(resolve, reject) {
var worker = new SharedWorker("mysharedworker");
worker.port.start();
worker.port.onmessage = function(e) {
if (e.data == "ack") {
resolve();
}
};
worker.onerror = reject;
});
}
function testNestedWorkerInSharedWorker() {
return new Promise(function(resolve, reject) {
var worker = new SharedWorker("myparentsharedworker");
worker.port.start();
worker.port.onmessage = function(e) {
if (e.data == "ack") {
resolve();
}
};
worker.onerror = reject;
});
}
function testCache() { function testCache() {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
// Issue an XHR that will be intercepted by the SW in order to start off // Issue an XHR that will be intercepted by the SW in order to start off
@ -383,6 +435,10 @@
testTrack(), testTrack(),
testXHR(), testXHR(),
testXSLT(), testXSLT(),
testWorker(),
testNestedWorker(),
testSharedWorker(),
testNestedWorkerInSharedWorker(),
// Also, test to see if the type of the request can be persisted in the database. // Also, test to see if the type of the request can be persisted in the database.
testCache(), testCache(),

View File

@ -0,0 +1,8 @@
onconnect = function(e) {
e.ports[0].start();
var worker = new Worker("myworker?shared");
worker.onmessage = function(e2) {
e.ports[0].postMessage(e2.data);
self.close();
};
};

View File

@ -0,0 +1,4 @@
var worker = new Worker("myworker");
worker.onmessage = function(e) {
postMessage(e.data);
};

View File

@ -0,0 +1,5 @@
onconnect = function(e) {
e.ports[0].start();
e.ports[0].postMessage("ack");
self.close();
};

View File

@ -0,0 +1 @@
postMessage("ack");

View File

@ -38,6 +38,10 @@ support-files =
fetch/context/beacon.sjs fetch/context/beacon.sjs
fetch/context/csp-violate.sjs fetch/context/csp-violate.sjs
fetch/context/ping.html fetch/context/ping.html
fetch/context/worker.js
fetch/context/parentworker.js
fetch/context/sharedworker.js
fetch/context/parentsharedworker.js
fetch/context/xml.xml fetch/context/xml.xml
fetch/https/index.html fetch/https/index.html
fetch/https/register.html fetch/https/register.html