diff --git a/netwerk/base/nsIPackagedAppService.idl b/netwerk/base/nsIPackagedAppService.idl index 1c20ebd576ca..35c359312d2f 100644 --- a/netwerk/base/nsIPackagedAppService.idl +++ b/netwerk/base/nsIPackagedAppService.idl @@ -8,6 +8,7 @@ interface nsIPrincipal; interface nsILoadContextInfo; interface nsICacheEntryOpenCallback; +interface nsILoadInfo; %{C++ #define PACKAGED_APP_TOKEN "!//" @@ -16,7 +17,7 @@ interface nsICacheEntryOpenCallback; /** * nsIPackagedAppService */ -[scriptable, builtinclass, uuid(f35e5229-d08a-46eb-a574-2db4e22aee98)] +[scriptable, builtinclass, uuid(b36efde7-6596-4082-a5fc-fc223148489f)] interface nsIPackagedAppService : nsISupports { /** @@ -44,6 +45,7 @@ interface nsIPackagedAppService : nsISupports * the cache. */ void getResource(in nsIPrincipal aPrincipal, + in nsILoadInfo aLoadInfo, in uint32_t aFlags, in nsILoadContextInfo aInfo, in nsICacheEntryOpenCallback aCallback); diff --git a/netwerk/protocol/http/PackagedAppService.cpp b/netwerk/protocol/http/PackagedAppService.cpp index d4d5fc136086..95365004d208 100644 --- a/netwerk/protocol/http/PackagedAppService.cpp +++ b/netwerk/protocol/http/PackagedAppService.cpp @@ -691,12 +691,13 @@ PackagedAppService::GetPackageURI(nsIURI *aURI, nsIURI **aPackageURI) NS_IMETHODIMP PackagedAppService::GetResource(nsIPrincipal *aPrincipal, + nsILoadInfo *aLoadInfo, uint32_t aLoadFlags, nsILoadContextInfo *aInfo, nsICacheEntryOpenCallback *aCallback) { // Check arguments are not null - if (!aPrincipal || !aCallback || !aInfo) { + if (!aPrincipal || !aLoadInfo || !aCallback || !aInfo) { return NS_ERROR_INVALID_ARG; } @@ -740,10 +741,10 @@ PackagedAppService::GetResource(nsIPrincipal *aPrincipal, } nsCOMPtr channel; - rv = NS_NewChannel( - getter_AddRefs(channel), packageURI, aPrincipal, - nsILoadInfo::SEC_NORMAL, nsIContentPolicy::TYPE_OTHER, nullptr, nullptr, - aLoadFlags); + rv = NS_NewChannelInternal( + getter_AddRefs(channel), packageURI, + aLoadInfo, + nullptr, nullptr, aLoadFlags); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -784,6 +785,10 @@ PackagedAppService::GetResource(nsIPrincipal *aPrincipal, nsRefPtr listener = new PackagedAppChannelListener(downloader, mimeConverter); + if (aLoadInfo->GetEnforceSecurity()) { + return channel->AsyncOpen2(listener); + } + return channel->AsyncOpen(listener, nullptr); } diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 81d612840dfd..0b041c9dad44 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -5220,8 +5220,8 @@ nsHttpChannel::BeginConnect() } nsCOMPtr principal = GetURIPrincipal(); - nsCOMPtr loadInfo = GetLoadContextInfo(this); - rv = pas->GetResource(principal, loadFlags, loadInfo, this); + nsCOMPtr loadContextInfo = GetLoadContextInfo(this); + rv = pas->GetResource(principal, mLoadInfo, loadFlags, loadContextInfo, this); if (NS_FAILED(rv)) { AsyncAbort(rv); } diff --git a/netwerk/test/unit/test_packaged_app_service.js b/netwerk/test/unit/test_packaged_app_service.js index b98a3e0b455b..ddd5182460d9 100644 --- a/netwerk/test/unit/test_packaged_app_service.js +++ b/netwerk/test/unit/test_packaged_app_service.js @@ -34,6 +34,7 @@ Cu.import('resource://gre/modules/LoadContextInfo.jsm'); Cu.import("resource://testing-common/httpd.js"); Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/NetUtil.jsm"); // The number of times this package has been requested // This number might be reset by tests that use it @@ -66,6 +67,11 @@ function getPrincipal(url) { return ssm.createCodebasePrincipal(uri, {}); } +function getLoadInfo(url) { + let tmpChannel = NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true}); + return tmpChannel.loadInfo; +} + // The package content // getData formats it as described at http://www.w3.org/TR/web-packaging/#streamable-package-format var testData = { @@ -179,10 +185,13 @@ var cacheListener = new packagedResourceListener(testData.content[0].data); // These calls should fail, since one of the arguments is invalid or null function test_bad_args() { - Assert.throws(() => { paservice.getResource(getPrincipal("http://test.com"), 0, LoadContextInfo.default, cacheListener); }, "url's with no !// aren't allowed"); - Assert.throws(() => { paservice.getResource(getPrincipal("http://test.com/package!//test"), 0, LoadContextInfo.default, null); }, "should have a callback"); - Assert.throws(() => { paservice.getResource(null, 0, LoadContextInfo.default, cacheListener); }, "should have a URI"); - Assert.throws(() => { paservice.getResource(getPrincipal("http://test.com/package!//test"), null, cacheListener); }, "should have a LoadContextInfo"); + let principal = getPrincipal("http://test.com/package!//test"); + let loadInfo = getLoadInfo("http://test.com/package!//test"); + Assert.throws(() => { paservice.getResource(getPrincipal("http://test.com"), loadInfo, 0, LoadContextInfo.default, cacheListener); }, "url's with no !// aren't allowed"); + Assert.throws(() => { paservice.getResource(principal, loadInfo, 0, LoadContextInfo.default, null); }, "should have a callback"); + Assert.throws(() => { paservice.getResource(null, loadInfo, 0, LoadContextInfo.default, cacheListener); }, "should have a principal"); + Assert.throws(() => { paservice.getResource(principal, loadInfo, 0, null, cacheListener); }, "should have a LoadContextInfo"); + Assert.throws(() => { paservice.getResource(principal, null, 0, LoadContextInfo.default, cacheListener); }, "should have a LoadInfo"); run_next_test(); } @@ -191,13 +200,15 @@ function test_bad_args() { // This tests that the callback gets called, and the cacheListener gets the proper content. function test_callback_gets_called() { packagePath = "/package"; - paservice.getResource(getPrincipal(uri + packagePath + "!//index.html"), 0, LoadContextInfo.default, cacheListener); + let url = uri + packagePath + "!//index.html"; + paservice.getResource(getPrincipal(url), getLoadInfo(url), 0, LoadContextInfo.default, cacheListener); } // Tests that requesting the same resource returns the same content function test_same_content() { packagePath = "/package"; - paservice.getResource(getPrincipal(uri + packagePath + "!//index.html"), 0, LoadContextInfo.default, cacheListener); + let url = uri + packagePath + "!//index.html"; + paservice.getResource(getPrincipal(url), getLoadInfo(url), 0, LoadContextInfo.default, cacheListener); } // Check the content handler has been called the expected number of times. @@ -209,7 +220,8 @@ function test_request_number() { // This tests that new content is returned if the package has been updated function test_updated_package() { packagePath = "/package"; - paservice.getResource(getPrincipal(uri + packagePath + "!//index.html"), 0, LoadContextInfo.default, + let url = uri + packagePath + "!//index.html"; + paservice.getResource(getPrincipal(url), getLoadInfo(url), 0, LoadContextInfo.default, new packagedResourceListener(testData.content[0].data.replace(/\.\.\./g, 'xxx'))); } @@ -233,13 +245,15 @@ var listener404 = { // Tests that an error is returned for a non existing package function test_package_does_not_exist() { packagePath = "/package_non_existent"; - paservice.getResource(getPrincipal(uri + packagePath + "!//index.html"), 0, LoadContextInfo.default, listener404); + let url = uri + packagePath + "!//index.html"; + paservice.getResource(getPrincipal(url), getLoadInfo(url), 0, LoadContextInfo.default, listener404); } // Tests that an error is returned for a non existing resource in a package function test_file_does_not_exist() { packagePath = "/package"; // This package exists - paservice.getResource(getPrincipal(uri + packagePath + "!//file_non_existent.html"), 0, LoadContextInfo.default, listener404); + let url = uri + packagePath + "!//file_non_existent.html"; + paservice.getResource(getPrincipal(url), getLoadInfo(url), 0, LoadContextInfo.default, listener404); } // ---------------------------------------------------------------------------- @@ -280,13 +294,15 @@ function packagedAppBadContentHandler(metadata, response) // Checks that the resource with the proper headers inside the bad package is still returned function test_bad_package() { packagePath = "/badPackage"; - paservice.getResource(getPrincipal(uri + packagePath + "!//index.html"), 0, LoadContextInfo.default, cacheListener); + let url = uri + packagePath + "!//index.html"; + paservice.getResource(getPrincipal(url), getLoadInfo(url), 0, LoadContextInfo.default, cacheListener); } // Checks that the request for a non-existent resource doesn't hang for a bad package function test_bad_package_404() { packagePath = "/badPackage"; - paservice.getResource(getPrincipal(uri + packagePath + "!//file_non_existent.html"), 0, LoadContextInfo.default, listener404); + let url = uri + packagePath + "!//file_non_existent.html"; + paservice.getResource(getPrincipal(url), getLoadInfo(url), 0, LoadContextInfo.default, listener404); } // ---------------------------------------------------------------------------- diff --git a/netwerk/test/unit/test_packaged_app_service_paths.js b/netwerk/test/unit/test_packaged_app_service_paths.js index ae660364a0f8..1c333088fcdd 100644 --- a/netwerk/test/unit/test_packaged_app_service_paths.js +++ b/netwerk/test/unit/test_packaged_app_service_paths.js @@ -1,6 +1,7 @@ Cu.import('resource://gre/modules/LoadContextInfo.jsm'); Cu.import("resource://testing-common/httpd.js"); Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/NetUtil.jsm"); var gRequestNo = 0; function packagedAppContentHandler(metadata, response) @@ -18,6 +19,11 @@ function getPrincipal(url) { return ssm.createCodebasePrincipal(uri, {}); } +function getLoadInfo(url) { + let tmpChannel = NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true}); + return tmpChannel.loadInfo; +} + var subresourcePaths = [ [ "/index.html", "index.html" ], [ "index.html", "index.html" ], @@ -119,7 +125,8 @@ function test_paths() { for (var i in subresourcePaths) { packagePath = "/package/" + i; dump("Iteration " + i + "\n"); - paservice.getResource(getPrincipal(uri + packagePath + "!//" + subresourcePaths[i][1]), 0, + let url = uri + packagePath + "!//" + subresourcePaths[i][1]; + paservice.getResource(getPrincipal(url), getLoadInfo(url), 0, LoadContextInfo.default, new packagedResourceListener(subresourcePaths[i][1], content)); yield undefined;