Bug 1057933 - ServiceWorkerRegistrations should use scope and not window to obtain workers. r=baku

--HG--
extra : rebase_source : 299337329af979f091fefd6b2d1ef202c547c5ed
This commit is contained in:
Nikhil Marathe 2014-08-24 22:35:03 -07:00
Родитель b1b56df2fe
Коммит d185ce387a
5 изменённых файлов: 89 добавлений и 31 удалений

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

@ -8,7 +8,7 @@
interface nsIDocument;
interface nsIURI;
[uuid(91b9d3fc-1654-44da-b438-15123cdbe7aa)]
[uuid(8d2f64db-5585-4876-a1c9-391e16549068)]
interface nsIServiceWorkerManager : nsISupports
{
/**
@ -61,10 +61,19 @@ interface nsIServiceWorkerManager : nsISupports
*/
[notxpcom,nostdcall] void MaybeStopControlling(in nsIDocument aDoc);
// Returns a ServiceWorker
[noscript] nsISupports GetInstalling(in nsIDOMWindow aWindow);
[noscript] nsISupports GetWaiting(in nsIDOMWindow aWindow);
[noscript] nsISupports GetActive(in nsIDOMWindow aWindow);
/*
* Returns a ServiceWorker.
* window is the window of the caller. scope is the registration's scope and must be
* a valid entry that window is allowed to load, otherwise this will return nullptr.
* These are only meant to be called from ServiceWorkerRegistration instances.
*/
[noscript] nsISupports GetInstalling(in nsIDOMWindow aWindow, in DOMString aScope);
[noscript] nsISupports GetWaiting(in nsIDOMWindow aWindow, in DOMString aScope);
[noscript] nsISupports GetActive(in nsIDOMWindow aWindow, in DOMString aScope);
/*
* Returns a ServiceWorker.
*/
[noscript] nsISupports GetDocumentController(in nsIDOMWindow aWindow);
// Testing

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

@ -1947,20 +1947,50 @@ ServiceWorkerManager::FireEventOnServiceWorkerRegistrations(
}
/*
* This is used for installing, waiting and active, and uses the registration
* most specifically matching the current scope.
* This is used for installing, waiting and active.
*/
NS_IMETHODIMP
ServiceWorkerManager::GetServiceWorkerForWindow(nsIDOMWindow* aWindow,
WhichServiceWorker aWhichWorker,
nsISupports** aServiceWorker)
ServiceWorkerManager::GetServiceWorkerForScope(nsIDOMWindow* aWindow,
const nsAString& aScope,
WhichServiceWorker aWhichWorker,
nsISupports** aServiceWorker)
{
AssertIsOnMainThread();
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window);
if (!window) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
MOZ_ASSERT(doc);
///////////////////////////////////////////
// Security check
nsCString scope = NS_ConvertUTF16toUTF8(aScope);
nsCOMPtr<nsIURI> scopeURI;
// We pass nullptr as the base URI since scopes obtained from
// ServiceWorkerRegistrations MUST be fully qualified URIs.
nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), scope, nullptr, nullptr);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIPrincipal> documentPrincipal = doc->NodePrincipal();
rv = documentPrincipal->CheckMayLoad(scopeURI, true /* report */,
false /* allowIfInheritsPrinciple */);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_DOM_SECURITY_ERR;
}
////////////////////////////////////////////
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(scope);
if (!domainInfo) {
return NS_ERROR_FAILURE;
}
nsRefPtr<ServiceWorkerRegistrationInfo> registration =
GetServiceWorkerRegistrationInfo(window);
domainInfo->GetRegistration(scope);
if (!registration) {
return NS_ERROR_FAILURE;
}
@ -1981,10 +2011,10 @@ ServiceWorkerManager::GetServiceWorkerForWindow(nsIDOMWindow* aWindow,
}
nsRefPtr<ServiceWorker> serviceWorker;
nsresult rv = CreateServiceWorkerForWindow(window,
info->GetScriptSpec(),
registration->mScope,
getter_AddRefs(serviceWorker));
rv = CreateServiceWorkerForWindow(window,
info->GetScriptSpec(),
registration->mScope,
getter_AddRefs(serviceWorker));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -2036,25 +2066,32 @@ ServiceWorkerManager::GetDocumentController(nsIDOMWindow* aWindow, nsISupports**
NS_IMETHODIMP
ServiceWorkerManager::GetInstalling(nsIDOMWindow* aWindow,
const nsAString& aScope,
nsISupports** aServiceWorker)
{
return GetServiceWorkerForWindow(aWindow, WhichServiceWorker::INSTALLING_WORKER,
aServiceWorker);
return GetServiceWorkerForScope(aWindow, aScope,
WhichServiceWorker::INSTALLING_WORKER,
aServiceWorker);
}
NS_IMETHODIMP
ServiceWorkerManager::GetWaiting(nsIDOMWindow* aWindow,
const nsAString& aScope,
nsISupports** aServiceWorker)
{
return GetServiceWorkerForWindow(aWindow, WhichServiceWorker::WAITING_WORKER,
aServiceWorker);
return GetServiceWorkerForScope(aWindow, aScope,
WhichServiceWorker::WAITING_WORKER,
aServiceWorker);
}
NS_IMETHODIMP
ServiceWorkerManager::GetActive(nsIDOMWindow* aWindow, nsISupports** aServiceWorker)
ServiceWorkerManager::GetActive(nsIDOMWindow* aWindow,
const nsAString& aScope,
nsISupports** aServiceWorker)
{
return GetServiceWorkerForWindow(aWindow, WhichServiceWorker::ACTIVE_WORKER,
aServiceWorker);
return GetServiceWorkerForScope(aWindow, aScope,
WhichServiceWorker::ACTIVE_WORKER,
aServiceWorker);
}
NS_IMETHODIMP

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

@ -361,9 +361,10 @@ private:
GetDomainInfo(const nsCString& aURL);
NS_IMETHODIMP
GetServiceWorkerForWindow(nsIDOMWindow* aWindow,
WhichServiceWorker aWhichWorker,
nsISupports** aServiceWorker);
GetServiceWorkerForScope(nsIDOMWindow* aWindow,
const nsAString& aScope,
WhichServiceWorker aWhichWorker,
nsISupports** aServiceWorker);
void
InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration,

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

@ -123,6 +123,11 @@ ServiceWorkerRegistration::Unregister(ErrorResult& aRv)
already_AddRefed<workers::ServiceWorker>
ServiceWorkerRegistration::GetWorkerReference(WhichServiceWorker aWhichOne)
{
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
if (!window) {
return nullptr;
}
nsresult rv;
nsCOMPtr<nsIServiceWorkerManager> swm =
do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv);
@ -133,13 +138,13 @@ ServiceWorkerRegistration::GetWorkerReference(WhichServiceWorker aWhichOne)
nsCOMPtr<nsISupports> serviceWorker;
switch(aWhichOne) {
case WhichServiceWorker::INSTALLING_WORKER:
rv = swm->GetInstalling(GetOwner(), getter_AddRefs(serviceWorker));
rv = swm->GetInstalling(window, mScope, getter_AddRefs(serviceWorker));
break;
case WhichServiceWorker::WAITING_WORKER:
rv = swm->GetWaiting(GetOwner(), getter_AddRefs(serviceWorker));
rv = swm->GetWaiting(window, mScope, getter_AddRefs(serviceWorker));
break;
case WhichServiceWorker::ACTIVE_WORKER:
rv = swm->GetActive(GetOwner(), getter_AddRefs(serviceWorker));
rv = swm->GetActive(window, mScope, getter_AddRefs(serviceWorker));
break;
default:
MOZ_CRASH("Invalid enum value");

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

@ -62,7 +62,13 @@
info(wr.scope);
ok(wr.scope == (new URL("realworker", document.baseURI)).href, "Scope should match");
// active, waiting, installing should return valid worker instances
// because the registration is for the realworker scope, so the workers
// should be obtained for that scope and not for
// test_installation_simple.html
var worker = wr.installing || wr.waiting || wr.active;
ok(worker && worker.scope.match(/realworker$/) &&
worker.url.match(/worker.js$/), "Valid worker instance should be available.");
}, function(e) {
info("Error: " + e.name);
ok(false, "realWorker Registration should have succeeded!");