--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -347,18 +347,16 @@
@RESPATH@/components/NotificationStorage.js
@RESPATH@/components/NotificationStorage.manifest
@RESPATH@/components/PermissionSettings.js
@RESPATH@/components/PermissionSettings.manifest
@RESPATH@/components/PermissionPromptService.js
@RESPATH@/components/PermissionPromptService.manifest
@RESPATH@/components/FeedProcessor.manifest
@RESPATH@/components/FeedProcessor.js
-@RESPATH@/components/PackagedAppUtils.manifest
-@RESPATH@/components/PackagedAppUtils.js
@RESPATH@/components/BrowserFeeds.manifest
@RESPATH@/components/FeedConverter.js
@RESPATH@/components/FeedWriter.js
@RESPATH@/components/WebContentConverter.js
@RESPATH@/components/BrowserComponents.manifest
@RESPATH@/components/nsBrowserContentHandler.js
@RESPATH@/components/nsBrowserGlue.js
@RESPATH@/components/nsSetDefaultBrowser.manifest
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -345,18 +345,16 @@
@RESPATH@/components/ConsoleAPI.manifest
@RESPATH@/components/ConsoleAPIStorage.js
@RESPATH@/components/BrowserElementParent.manifest
@RESPATH@/components/BrowserElementParent.js
@RESPATH@/components/BrowserElementProxy.manifest
@RESPATH@/components/BrowserElementProxy.js
@RESPATH@/components/FeedProcessor.manifest
@RESPATH@/components/FeedProcessor.js
-@RESPATH@/components/PackagedAppUtils.js
-@RESPATH@/components/PackagedAppUtils.manifest
@RESPATH@/components/WellKnownOpportunisticUtils.js
@RESPATH@/components/WellKnownOpportunisticUtils.manifest
#ifndef XP_MACOSX
; OSX uses native platform impl. Windows, Linux, and Android uses fallback JS impl.
@BINPATH@/components/nsDNSServiceDiscovery.manifest
@BINPATH@/components/nsDNSServiceDiscovery.js
#endif
@RESPATH@/browser/components/BrowserFeeds.manifest
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -277,18 +277,16 @@
@BINPATH@/components/SettingsManager.js
@BINPATH@/components/SettingsManager.manifest
@BINPATH@/components/BrowserElementParent.manifest
@BINPATH@/components/BrowserElementParent.js
@BINPATH@/components/BrowserElementProxy.manifest
@BINPATH@/components/BrowserElementProxy.js
@BINPATH@/components/FeedProcessor.manifest
@BINPATH@/components/FeedProcessor.js
-@BINPATH@/components/PackagedAppUtils.manifest
-@BINPATH@/components/PackagedAppUtils.js
@BINPATH@/components/WellKnownOpportunisticUtils.js
@BINPATH@/components/WellKnownOpportunisticUtils.manifest
@BINPATH@/components/PermissionSettings.js
@BINPATH@/components/PermissionSettings.manifest
@BINPATH@/components/PermissionPromptService.js
@BINPATH@/components/PermissionPromptService.manifest
@BINPATH@/components/nsDNSServiceDiscovery.manifest
@BINPATH@/components/nsDNSServiceDiscovery.js
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1589,26 +1589,16 @@ pref("network.http.tcp_keepalive.short_l
pref("network.http.tcp_keepalive.short_lived_idle_time", 10);
pref("network.http.tcp_keepalive.long_lived_connections", true);
pref("network.http.tcp_keepalive.long_lived_idle_time", 600);
pref("network.http.enforce-framing.http1", false); // should be named "strict"
pref("network.http.enforce-framing.soft", true);
-// Whether nsHttpChannel should use the PackagedAppService to load
-// resources from a package when directed to a URL
-// such as http://domain.com/package.pak!//resource.html
-// See http://www.w3.org/TR/web-packaging/#streamable-package-format
-pref("network.http.enable-packaged-apps", false);
-
-// Enable this to bring in the signature verification if the signature exists.
-// Set to false if you don't need the signed packaged web app support (i.e. NSec).
-pref("network.http.signed-packages.enabled", false);
-
// If it is set to false, headers with empty value will not appear in the header
// array - behavior as it used to be. If it is true: empty headers coming from
// the network will exist in header array as empty string. Call SetHeader with
// an empty value will still delete the header.(Bug 6699259)
pref("network.http.keep_empty_response_headers_as_empty_string", true);
// Max size, in bytes, for received HTTP response header.
pref("network.http.max_response_header_size", 393216);
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -68,19 +68,16 @@ XPIDL_SOURCES += [
'nsINetworkInfoService.idl',
'nsINetworkInterceptController.idl',
'nsINetworkLinkService.idl',
'nsINetworkPredictor.idl',
'nsINetworkPredictorVerifier.idl',
'nsINetworkProperties.idl',
'nsINSSErrorsService.idl',
'nsINullChannel.idl',
- 'nsIPackagedAppService.idl',
- 'nsIPackagedAppUtils.idl',
- 'nsIPackagedAppVerifier.idl',
'nsIParentChannel.idl',
'nsIParentRedirectingChannel.idl',
'nsIPermission.idl',
'nsIPermissionManager.idl',
'nsIPrivateBrowsingChannel.idl',
'nsIProgressEventSink.idl',
'nsIPrompt.idl',
'nsIProtocolHandler.idl',
deleted file mode 100644
--- a/netwerk/base/nsIPackagedAppService.idl
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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 "nsISupports.idl"
-
-interface nsIChannel;
-interface nsICacheEntryOpenCallback;
-
-%{C++
- #define PACKAGED_APP_TOKEN "!//"
-%}
-
-/**
- * nsIPackagedAppService
- */
-[scriptable, builtinclass, uuid(9c96c638-e80c-4dce-abec-c96fdb7a25d8)]
-interface nsIPackagedAppService : nsISupports
-{
- /**
- * @param aChannel
- * this param is passed to the packaged app service in order to provide
- * info about the requesting channel, which wants to access the contents
- * of a packaged app resource. Its URI has the following format:
- * http://domain.com/path/to/package.pak!//path/to/subresource.html
- *
- * @param aCallback
- * an object implementing nsICacheEntryOpenCallback
- * this is the target of the async result of the operation
- * aCallback->OnCacheEntryCheck() is called to verify the entry is valid
- * aCallback->OnCacheEntryAvailable() is called with a pointer to the
- * the cached entry, if one exists, or an error code otherwise
- * aCallback is kept alive using an nsCOMPtr until OnCacheEntryAvailable
- * is called
- *
- * Calling this method will either download the package containing the given
- * resource URI, store it in the cache and pass the cache entry to aCallback,
- * or if that resource has already been downloaded it will be served from
- * the cache.
- */
- void getResource(in nsIChannel aChannel,
- in nsICacheEntryOpenCallback aCallback);
-};
deleted file mode 100644
--- a/netwerk/base/nsIPackagedAppUtils.idl
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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 "nsISupports.idl"
-
-interface nsIVerificationCallback;
-
-%{C++
-#define NS_PACKAGEDAPPUTILS_CONTRACTID "@mozilla.org/network/packaged-app-utils;1"
-%}
-
-/**
- * A package using privileged APIs should be signed by marketplace or trust-
- * worthy developers. When Necko receives such a package, it has to
- * extract the manifest and the signature and calls verifyManifest(...) to verify
- * the manifest. nsIPackagedAppUtils will parse the manifest and
- * store the hash values of each resource. When a resource is ready, Necko
- * will calculate its hash value (including the header like Content-Location: xxx),
- * and calls checkIntegrity(...) to verify the integrity.
- *
- * For more detail:
- * https://wiki.mozilla.org/FirefoxOS/New_security_model/Packaging
- */
-
-[scriptable, uuid(2963609c-370b-4a76-9858-6f05121d0473)]
-interface nsIPackagedAppUtils : nsISupports
-{
- /**
- * @aHeader is the package's header including
- * - "manifest-signature: xxxxxx" (base64 encoding)
- * @aManifest is the manifest of the package
- * - the multipart header is included
- * - manifest must be the first resource of the package
- * @aCallback is the callback, see comments of nsIVerificationCallback below
- */
- void verifyManifest(in ACString aHeader,
- in ACString aManifest,
- in nsIVerificationCallback aVerifier,
- in boolean aDeveloperMode);
-
- /**
- * @aFileName is the name of a resource in the package
- * @aHashValue is the hash value of this resource named aFileName
- * - aHashValue should be computed by the caller of this method
- * @aCallback is the callback, see comments of nsIVerificationCallback below
- */
- void checkIntegrity(in ACString aFileName,
- in ACString aHashValue,
- in nsIVerificationCallback aVerifier);
-
- /**
- * The package identifier for signed package. Only available after the
- * manifest is verified.
- */
- readonly attribute ACString packageIdentifier;
-
- /**
- * The moz-package-location in the manifest of this signed package.
- * Only available after the manifest is verified.
- */
- readonly attribute ACString packageOrigin;
-};
-
-/**
- * The callback passed to verifyManifest and checkIntegrity
- */
-[scriptable, uuid(e1912028-93e5-4378-aa3f-a58702937169)]
-interface nsIVerificationCallback : nsISupports
-{
- /**
- * @aForManifest
- * - true if it's called by verifyManifest
- * - false if it's called by checkIntegrity
- * @aSuccess
- * - true if the verification succeeds, false otherwise
- */
- void fireVerifiedEvent(in boolean aForManifest,
- in boolean aSuccess);
-};
deleted file mode 100644
--- a/netwerk/base/nsIPackagedAppVerifier.idl
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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 "nsISupports.idl"
-#include "nsIStreamListener.idl"
-
-interface nsIURI;
-interface nsICacheEntry;
-interface nsIPackagedAppVerifierListener;
-
-/**
- * nsIPackagedAppVerifier
- *
- * It inherits nsIStreamListener and all the data will be fed by
- * onStartRequest/onDataAvailable/onStopRequest.
- *
- */
-[scriptable, uuid(37a5c208-0fce-4ad6-8431-aeb904dfe543)]
-interface nsIPackagedAppVerifier : nsIStreamListener
-{
- // The package identifier of the signed package. For a unsigned package, this
- // attribute is empty.
- readonly attribute ACString packageIdentifier;
-
- // Whether this package is signed.
- readonly attribute boolean isPackageSigned;
-
- /**
- * @param aListener
- * an object implementing nsIPackagedAppVerifierListener as the bridge that
- * the client gets callback from the package verifier. The callback might be
- * sync or async depending on the implementation.
- *
- * @param aPackageOrigin
- * the origin of the package. It will be updated based on the package
- * identifier defined in the manifest.
- *
- * @param aSignature
- * the signature of the package we desire to verify against. See
- * https://wiki.mozilla.org/User:Ptheriault/Packagedprivilegedcontent#The_Signed_Manifest
- * for further information.
- *
- * @param aPackageCacheEntry
- * the cache entry of the package itself (not the resource's cache).
- * It will be used to store any necessary information like the signed
- * package origin.
- *
- * The verifier init function.
- */
- void init(in nsIPackagedAppVerifierListener aListener,
- in ACString aPackageOrigin,
- in ACString aSignature,
- in nsICacheEntry aPackageCacheEntry);
-
- /**
- * @param aUri
- * the URI of the resource.
- *
- * @param aCacheEntry
- * the cache entry of the resource.
- *
- * @param aStatusCode
- * the status code of the resource we just finished download.
- *
- * @param aIsLastPart
- * whether this resource is the last one in the package.
- *
- * Create an object that we will pass to the verifier as a user context
- * through onStartRequest. The main purpose of this function is to make
- * nsIPackagedAppVerifier xpcshell-testable. See test_packaged_app_verifier.js.
- *
- */
- nsISupports createResourceCacheInfo(in nsIURI aUri,
- in nsICacheEntry aCacheEntry,
- in nsresult aStatusCode,
- in boolean aIsLastPart);
-};
-
-/**
- * nsIPackagedAppVerifierListener
- */
-[scriptable, uuid(092eba70-4cbf-11e5-b970-0800200c9a66)]
-interface nsIPackagedAppVerifierListener : nsISupports
-{
- /**
- * @param aIsManifest
- * indicate if this callback is for manifest or not. True for manifest and false
- * for resource.
- *
- * @param aUri
- * the URI of the resource that has just been verified.
- *
- * @param aCacheEntry
- * the cache entry of the resource that has just been verified.
- *
- * @param aStatusCode
- * the resource download status code from nsIMultipartChannel.
- *
- * @param aIsLastPart
- * indicate if the verified resource is that last one in the package.
- *
- * @param aVerificationSuccess
- * the verification result.
- *
- * Callback'ed when a manifest/resource is verified.
- */
- void onVerified(in boolean aIsManifest,
- in nsIURI aUri,
- in nsICacheEntry aCacheEntry,
- in nsresult aStatusCode,
- in boolean aIsLastPart,
- in boolean aVerificationSuccess);
-};
-
--- a/netwerk/build/nsNetCID.h
+++ b/netwerk/build/nsNetCID.h
@@ -890,36 +890,16 @@
#define NS_DASHBOARD_CID \
{ /*c79eb3c6-091a-45a6-8544-5a8d1ab79537 */ \
0xc79eb3c6, \
0x091a, \
0x45a6, \
{ 0x85, 0x44, 0x5a, 0x8d, 0x1a, 0xb7, 0x95, 0x37 } \
}
-#define NS_PACKAGEDAPPSERVICE_CONTRACTID \
- "@mozilla.org/network/packaged-app-service;1"
-#define NS_PACKAGEDAPPSERVICE_CID \
-{ /* adef6762-41b9-4470-a06a-dc29cf8de381 */ \
- 0xadef6762, \
- 0x41b9, \
- 0x4470, \
- { 0xa0, 0x6a, 0xdc, 0x29, 0xcf, 0x8d, 0xe3, 0x81 } \
-}
-
-#define NS_PACKAGEDAPPVERIFIER_CONTRACTID \
- "@mozilla.org/network/packaged-app-verifier;1"
-#define NS_PACKAGEDAPPVERIFIER_CID \
-{ /* 07242d20-4cae-11e5-b970-0800200c9a66 */ \
- 0x07242d20, \
- 0x4cae, \
- 0x11e5, \
- { 0xb9, 0x70, 0x08, 0x00, 0x20, 0x0c, 0x96, 0x66 } \
-}
-
/******************************************************************************
* netwerk/cookie classes
*/
// service implementing nsICookieManager and nsICookieManager2.
#define NS_COOKIEMANAGER_CONTRACTID \
"@mozilla.org/cookiemanager;1"
#define NS_COOKIEMANAGER_CID \
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -280,23 +280,19 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpAct
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpBasicAuth)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDigestAuth)
NS_GENERIC_FACTORY_CONSTRUCTOR(ThrottleQueue)
} // namespace net
} // namespace mozilla
#endif // !NECKO_PROTOCOL_http
#include "mozilla/net/Dashboard.h"
-#include "mozilla/net/PackagedAppService.h"
-#include "mozilla/net/PackagedAppVerifier.h"
namespace mozilla {
namespace net {
NS_GENERIC_FACTORY_CONSTRUCTOR(Dashboard)
- NS_GENERIC_FACTORY_CONSTRUCTOR(PackagedAppService)
- NS_GENERIC_FACTORY_CONSTRUCTOR(PackagedAppVerifier)
} // namespace net
} // namespace mozilla
#ifdef NECKO_PROTOCOL_res
// resource
#include "nsResProtocolHandler.h"
#include "ExtensionProtocolHandler.h"
#include "SubstitutingProtocolHandler.h"
@@ -459,17 +455,16 @@ nsresult NS_NewMultiMixedConv (nsMultiMi
nsresult MOZ_NewTXTToHTMLConv (mozTXTToHTMLConv** result);
nsresult NS_NewHTTPCompressConv (mozilla::net::nsHTTPCompressConv ** result);
nsresult NS_NewStreamConv(nsStreamConverterService **aStreamConv);
#define FTP_TO_INDEX "?from=text/ftp-dir&to=application/http-index-format"
#define INDEX_TO_HTML "?from=application/http-index-format&to=text/html"
#define MULTI_MIXED_X "?from=multipart/x-mixed-replace&to=*/*"
#define MULTI_MIXED "?from=multipart/mixed&to=*/*"
-#define APPLICATION_PACKAGE_CONV "?from=" APPLICATION_PACKAGE "&to=*/*"
#define MULTI_BYTERANGES "?from=multipart/byteranges&to=*/*"
#define UNKNOWN_CONTENT "?from=" UNKNOWN_CONTENT_TYPE "&to=*/*"
#define GZIP_TO_UNCOMPRESSED "?from=gzip&to=uncompressed"
#define XGZIP_TO_UNCOMPRESSED "?from=x-gzip&to=uncompressed"
#define BROTLI_TO_UNCOMPRESSED "?from=br&to=uncompressed"
#define COMPRESS_TO_UNCOMPRESSED "?from=compress&to=uncompressed"
#define XCOMPRESS_TO_UNCOMPRESSED "?from=x-compress&to=uncompressed"
#define DEFLATE_TO_UNCOMPRESSED "?from=deflate&to=uncompressed"
@@ -479,17 +474,16 @@ nsresult NS_NewStreamConv(nsStreamConver
#define BINHEX_TO_WILD "?from=application/mac-binhex40&to=*/*"
#endif
static const mozilla::Module::CategoryEntry kNeckoCategories[] = {
{ NS_ISTREAMCONVERTER_KEY, FTP_TO_INDEX, "" },
{ NS_ISTREAMCONVERTER_KEY, INDEX_TO_HTML, "" },
{ NS_ISTREAMCONVERTER_KEY, MULTI_MIXED_X, "" },
{ NS_ISTREAMCONVERTER_KEY, MULTI_MIXED, "" },
- { NS_ISTREAMCONVERTER_KEY, APPLICATION_PACKAGE_CONV, "" },
{ NS_ISTREAMCONVERTER_KEY, MULTI_BYTERANGES, "" },
{ NS_ISTREAMCONVERTER_KEY, UNKNOWN_CONTENT, "" },
{ NS_ISTREAMCONVERTER_KEY, GZIP_TO_UNCOMPRESSED, "" },
{ NS_ISTREAMCONVERTER_KEY, XGZIP_TO_UNCOMPRESSED, "" },
{ NS_ISTREAMCONVERTER_KEY, BROTLI_TO_UNCOMPRESSED, "" },
{ NS_ISTREAMCONVERTER_KEY, COMPRESS_TO_UNCOMPRESSED, "" },
{ NS_ISTREAMCONVERTER_KEY, XCOMPRESS_TO_UNCOMPRESSED, "" },
{ NS_ISTREAMCONVERTER_KEY, DEFLATE_TO_UNCOMPRESSED, "" },
@@ -757,18 +751,16 @@ NS_DEFINE_NAMED_CID(NS_NOAUTHURLPARSER_C
NS_DEFINE_NAMED_CID(NS_AUTHURLPARSER_CID);
NS_DEFINE_NAMED_CID(NS_STANDARDURL_CID);
NS_DEFINE_NAMED_CID(NS_ARRAYBUFFERINPUTSTREAM_CID);
NS_DEFINE_NAMED_CID(NS_BUFFEREDINPUTSTREAM_CID);
NS_DEFINE_NAMED_CID(NS_BUFFEREDOUTPUTSTREAM_CID);
NS_DEFINE_NAMED_CID(NS_MIMEINPUTSTREAM_CID);
NS_DEFINE_NAMED_CID(NS_PROTOCOLPROXYSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_STREAMCONVERTERSERVICE_CID);
-NS_DEFINE_NAMED_CID(NS_PACKAGEDAPPSERVICE_CID);
-NS_DEFINE_NAMED_CID(NS_PACKAGEDAPPVERIFIER_CID);
NS_DEFINE_NAMED_CID(NS_DASHBOARD_CID);
#ifdef NECKO_PROTOCOL_ftp
NS_DEFINE_NAMED_CID(NS_FTPDIRLISTINGCONVERTER_CID);
#endif
NS_DEFINE_NAMED_CID(NS_NSINDEXEDTOHTMLCONVERTER_CID);
NS_DEFINE_NAMED_CID(NS_DIRINDEXPARSER_CID);
NS_DEFINE_NAMED_CID(NS_MULTIMIXEDCONVERTER_CID);
NS_DEFINE_NAMED_CID(NS_UNKNOWNDECODER_CID);
@@ -905,18 +897,16 @@ static const mozilla::Module::CIDEntry k
{ &kNS_AUTHURLPARSER_CID, false, nullptr, nsAuthURLParserConstructor },
{ &kNS_STANDARDURL_CID, false, nullptr, nsStandardURLConstructor },
{ &kNS_ARRAYBUFFERINPUTSTREAM_CID, false, nullptr, ArrayBufferInputStreamConstructor },
{ &kNS_BUFFEREDINPUTSTREAM_CID, false, nullptr, nsBufferedInputStream::Create },
{ &kNS_BUFFEREDOUTPUTSTREAM_CID, false, nullptr, nsBufferedOutputStream::Create },
{ &kNS_MIMEINPUTSTREAM_CID, false, nullptr, nsMIMEInputStreamConstructor },
{ &kNS_PROTOCOLPROXYSERVICE_CID, true, nullptr, nsProtocolProxyServiceConstructor },
{ &kNS_STREAMCONVERTERSERVICE_CID, false, nullptr, CreateNewStreamConvServiceFactory },
- { &kNS_PACKAGEDAPPSERVICE_CID, false, NULL, mozilla::net::PackagedAppServiceConstructor },
- { &kNS_PACKAGEDAPPVERIFIER_CID, false, NULL, mozilla::net::PackagedAppVerifierConstructor },
{ &kNS_DASHBOARD_CID, false, nullptr, mozilla::net::DashboardConstructor },
#ifdef NECKO_PROTOCOL_ftp
{ &kNS_FTPDIRLISTINGCONVERTER_CID, false, nullptr, CreateNewFTPDirListingConv },
#endif
{ &kNS_NSINDEXEDTOHTMLCONVERTER_CID, false, nullptr, nsIndexedToHTML::Create },
{ &kNS_DIRINDEXPARSER_CID, false, nullptr, nsDirIndexParserConstructor },
{ &kNS_MULTIMIXEDCONVERTER_CID, false, nullptr, CreateNewMultiMixedConvFactory },
{ &kNS_UNKNOWNDECODER_CID, false, nullptr, CreateNewUnknownDecoderFactory },
@@ -1055,28 +1045,25 @@ static const mozilla::Module::ContractID
{ NS_AUTHURLPARSER_CONTRACTID, &kNS_AUTHURLPARSER_CID },
{ NS_STANDARDURL_CONTRACTID, &kNS_STANDARDURL_CID },
{ NS_ARRAYBUFFERINPUTSTREAM_CONTRACTID, &kNS_ARRAYBUFFERINPUTSTREAM_CID },
{ NS_BUFFEREDINPUTSTREAM_CONTRACTID, &kNS_BUFFEREDINPUTSTREAM_CID },
{ NS_BUFFEREDOUTPUTSTREAM_CONTRACTID, &kNS_BUFFEREDOUTPUTSTREAM_CID },
{ NS_MIMEINPUTSTREAM_CONTRACTID, &kNS_MIMEINPUTSTREAM_CID },
{ NS_PROTOCOLPROXYSERVICE_CONTRACTID, &kNS_PROTOCOLPROXYSERVICE_CID },
{ NS_STREAMCONVERTERSERVICE_CONTRACTID, &kNS_STREAMCONVERTERSERVICE_CID },
- { NS_PACKAGEDAPPSERVICE_CONTRACTID, &kNS_PACKAGEDAPPSERVICE_CID },
- { NS_PACKAGEDAPPVERIFIER_CONTRACTID, &kNS_PACKAGEDAPPVERIFIER_CID },
{ NS_DASHBOARD_CONTRACTID, &kNS_DASHBOARD_CID },
#ifdef NECKO_PROTOCOL_ftp
{ NS_ISTREAMCONVERTER_KEY FTP_TO_INDEX, &kNS_FTPDIRLISTINGCONVERTER_CID },
#endif
{ NS_ISTREAMCONVERTER_KEY INDEX_TO_HTML, &kNS_NSINDEXEDTOHTMLCONVERTER_CID },
{ NS_DIRINDEXPARSER_CONTRACTID, &kNS_DIRINDEXPARSER_CID },
{ NS_ISTREAMCONVERTER_KEY MULTI_MIXED_X, &kNS_MULTIMIXEDCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY MULTI_BYTERANGES, &kNS_MULTIMIXEDCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY MULTI_MIXED, &kNS_MULTIMIXEDCONVERTER_CID },
- { NS_ISTREAMCONVERTER_KEY APPLICATION_PACKAGE_CONV, &kNS_MULTIMIXEDCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY UNKNOWN_CONTENT, &kNS_UNKNOWNDECODER_CID },
{ NS_GENERIC_CONTENT_SNIFFER, &kNS_UNKNOWNDECODER_CID },
{ NS_BINARYDETECTOR_CONTRACTID, &kNS_BINARYDETECTOR_CID },
{ NS_ISTREAMCONVERTER_KEY GZIP_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY XGZIP_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY BROTLI_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY COMPRESS_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY XCOMPRESS_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
deleted file mode 100644
--- a/netwerk/protocol/http/PackagedAppService.cpp
+++ /dev/null
@@ -1,1175 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et 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 "PackagedAppService.h"
-#include "nsICacheStorage.h"
-#include "LoadContextInfo.h"
-#include "nsICacheStorageService.h"
-#include "nsIResponseHeadProvider.h"
-#include "nsIMultiPartChannel.h"
-#include "../../cache2/CacheFileUtils.h"
-#include "nsStreamUtils.h"
-#include "mozilla/DebugOnly.h"
-#include "nsIHttpHeaderVisitor.h"
-#include "mozilla/LoadContext.h"
-#include "nsIInstallPackagedWebapp.h"
-#include "mozilla/Logging.h"
-#include "nsHttpResponseHead.h"
-#include "nsICachingChannel.h"
-#include "nsStringStream.h"
-#include "nsIOutputStream.h"
-#include "nsIInputStream.h"
-#include "nsNetUtil.h"
-#include "nsICacheEntryOpenCallback.h"
-#include "nsIURL.h"
-#include "nsContentUtils.h"
-#include "nsIStreamConverterService.h"
-#include "nsMimeTypes.h"
-
-namespace mozilla {
-namespace net {
-
-static PackagedAppService *gPackagedAppService = nullptr;
-static LazyLogModule gPASLog("PackagedAppService");
-#define LOG_PAS(args) MOZ_LOG(gPASLog, mozilla::LogLevel::Debug, args)
-
-NS_IMPL_ISUPPORTS(PackagedAppService, nsIPackagedAppService)
-
-NS_IMPL_ISUPPORTS(PackagedAppService::CacheEntryWriter, nsIStreamListener)
-
-static void
-LogURI(const char *aFunctionName, void *self, nsIURI *aURI, nsILoadContextInfo *aInfo = nullptr)
-{
- if (MOZ_LOG_TEST(gPASLog, LogLevel::Debug)) {
- nsAutoCString spec;
- if (aURI) {
- aURI->GetAsciiSpec(spec);
- } else {
- spec = "(null)";
- }
-
- nsAutoCString prefix;
- if (aInfo) {
- CacheFileUtils::AppendKeyPrefix(aInfo, prefix);
- prefix += ":";
- }
-
- LOG_PAS(("[%p] %s > %s%s\n", self, aFunctionName, prefix.get(), spec.get()));
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-/* static */ nsresult
-PackagedAppService::CacheEntryWriter::Create(nsIURI *aURI,
- nsICacheStorage *aStorage,
- CacheEntryWriter **aResult)
-{
- RefPtr<CacheEntryWriter> writer = new CacheEntryWriter();
- nsresult rv = aStorage->OpenTruncate(aURI, EmptyCString(),
- getter_AddRefs(writer->mEntry));
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- rv = writer->mEntry->ForceValidFor(PR_UINT32_MAX);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- writer.forget(aResult);
- return NS_OK;
-}
-
-nsresult
-PackagedAppService::CacheEntryWriter::CopySecurityInfo(nsIChannel *aChannel)
-{
- if (!aChannel) {
- return NS_ERROR_INVALID_ARG;
- }
-
- nsCOMPtr<nsISupports> securityInfo;
- aChannel->GetSecurityInfo(getter_AddRefs(securityInfo));
- if (securityInfo) {
- mEntry->SetSecurityInfo(securityInfo);
- }
-
- return NS_OK;
-}
-
-namespace { // anon
-
-class HeaderCopier final : public nsIHttpHeaderVisitor
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIHTTPHEADERVISITOR
-
- explicit HeaderCopier(nsHttpResponseHead* aHead)
- : mHead(aHead)
- {
- }
-
-private:
- ~HeaderCopier() {}
- bool ShouldCopy(const nsACString& aHeader) const;
-
- nsHttpResponseHead* mHead;
-};
-
-NS_IMPL_ISUPPORTS(HeaderCopier, nsIHttpHeaderVisitor)
-
-NS_IMETHODIMP
-HeaderCopier::VisitHeader(const nsACString& aHeader, const nsACString& aValue)
-{
- if (!ShouldCopy(aHeader)) {
- return NS_OK;
- }
-
- return mHead->SetHeader(nsHttp::ResolveAtom(aHeader), aValue);
-}
-
-bool
-HeaderCopier::ShouldCopy(const nsACString &aHeader) const
-{
- nsHttpAtom header = nsHttp::ResolveAtom(aHeader);
-
- // Don't overwrite the existing headers.
- if (mHead->HasHeader(header)) {
- return false;
- }
-
- // A black list of headers we shouldn't copy.
- static const nsHttpAtom kHeadersCopyBlacklist[] = {
- nsHttp::Authentication,
- nsHttp::Cache_Control,
- nsHttp::Connection,
- nsHttp::Content_Disposition,
- nsHttp::Content_Encoding,
- nsHttp::Content_Language,
- nsHttp::Content_Length,
- nsHttp::Content_Location,
- nsHttp::Content_MD5,
- nsHttp::Content_Range,
- nsHttp::Content_Type,
- nsHttp::ETag,
- nsHttp::Last_Modified,
- nsHttp::Proxy_Authenticate,
- nsHttp::Proxy_Connection,
- nsHttp::Set_Cookie,
- nsHttp::Set_Cookie2,
- nsHttp::TE,
- nsHttp::Trailer,
- nsHttp::Transfer_Encoding,
- nsHttp::Vary,
- nsHttp::WWW_Authenticate,
- };
-
- // Loop through the black list to check if we should copy this header.
- for (uint32_t i = 0; i < mozilla::ArrayLength(kHeadersCopyBlacklist); i++) {
- if (header == kHeadersCopyBlacklist[i]) {
- return false;
- }
- }
-
- return true;
-}
-
-// Helper function to get the package cache entry from the request. The request
-// could be from multipart channel or the package channel.
-static already_AddRefed<nsICacheEntry>
-GetPackageCacheEntry(nsIRequest *aRequest)
-{
- nsCOMPtr<nsIChannel> baseChannel;
-
- nsCOMPtr<nsIMultiPartChannel> multiChannel(do_QueryInterface(aRequest));
- if (multiChannel) {
- // If it's a request from multipart channel, get the base channel from it.
- multiChannel->GetBaseChannel(getter_AddRefs(baseChannel));
- } else {
- // Otherwise, the request is from the package channel.
- baseChannel = do_QueryInterface(aRequest);
- }
-
- if (!baseChannel) {
- return nullptr;
- }
-
- nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(baseChannel);
- if (!cachingChannel) {
- return nullptr;
- }
-
- nsCOMPtr<nsISupports> cacheToken;
- cachingChannel->GetCacheToken(getter_AddRefs(cacheToken));
- if (!cacheToken) {
- return nullptr;
- }
-
- nsCOMPtr<nsICacheEntry> entry(do_QueryInterface(cacheToken));
-
- return entry.forget();
-}
-
-// Create nsIInputStream based on the given string which doesn't have to
-// be null-terminated. Note that the string data is shared.
-static already_AddRefed<nsIInputStream>
-CreateSharedStringStream(const char* aData, uint32_t aCount)
-{
- nsresult rv;
- nsCOMPtr<nsIStringInputStream> stream =
- do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
- NS_ENSURE_SUCCESS(rv, nullptr);
-
- rv = stream->ShareData((char*)aData, aCount);
- NS_ENSURE_SUCCESS(rv, nullptr);
-
- return stream.forget();
-}
-
-// Get the original HTTP response header from the request.
-static bool
-GetOriginalResponseHeader(nsIRequest* aRequest, nsACString& aHeader)
-{
- nsCOMPtr<nsIMultiPartChannel> multiPartChannel(do_QueryInterface(aRequest));
- if (!multiPartChannel) {
- return false;
- }
-
- multiPartChannel->GetOriginalResponseHeader(aHeader);
-
- return true;
-}
-
-} // anon
-
-/* static */ nsresult
-PackagedAppService::CacheEntryWriter::CopyHeadersFromChannel(nsIChannel *aChannel,
- nsHttpResponseHead *aHead)
-{
- if (!aChannel || !aHead) {
- return NS_ERROR_INVALID_ARG;
- }
-
- nsCOMPtr<nsIHttpChannel> httpChan = do_QueryInterface(aChannel);
- if (!httpChan) {
- return NS_ERROR_FAILURE;
- }
-
- RefPtr<HeaderCopier> headerCopier = new HeaderCopier(aHead);
- return httpChan->VisitResponseHeaders(headerCopier);
-}
-
-nsresult
-PackagedAppService::CacheEntryWriter::ConsumeData(const char *aBuf,
- uint32_t aCount,
- uint32_t *aWriteCount)
-{
- MOZ_ASSERT(mOutputStream, "The stream should not be null");
- return mOutputStream->Write(aBuf, aCount, aWriteCount);
-}
-
-NS_IMETHODIMP
-PackagedAppService::CacheEntryWriter::OnStartRequest(nsIRequest *aRequest,
- nsISupports *aContext)
-{
- nsresult rv;
- nsCOMPtr<nsIResponseHeadProvider> provider(do_QueryInterface(aRequest));
- if (!provider) {
- return NS_ERROR_INVALID_ARG;
- }
- nsHttpResponseHead *responseHead = provider->GetResponseHead();
- if (!responseHead) {
- return NS_ERROR_FAILURE;
- }
-
- mEntry->SetPredictedDataSize(responseHead->TotalEntitySize());
-
- rv = mEntry->SetMetaDataElement("request-method", "GET");
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- nsCOMPtr<nsIMultiPartChannel> multiPartChannel = do_QueryInterface(aRequest);
- if (!multiPartChannel) {
- return NS_ERROR_FAILURE;
- }
- nsCOMPtr<nsIChannel> baseChannel;
- multiPartChannel->GetBaseChannel(getter_AddRefs(baseChannel));
-
- rv = CopySecurityInfo(baseChannel);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- rv = CopyHeadersFromChannel(baseChannel, responseHead);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- nsAutoCString head;
- responseHead->Flatten(head, true);
- rv = mEntry->SetMetaDataElement("response-head", head.get());
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- rv = mEntry->OpenOutputStream(0, getter_AddRefs(mOutputStream));
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-PackagedAppService::CacheEntryWriter::OnStopRequest(nsIRequest *aRequest,
- nsISupports *aContext,
- nsresult aStatusCode)
-{
- if (mOutputStream) {
- mOutputStream->Close();
- mOutputStream = nullptr;
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-PackagedAppService::CacheEntryWriter::OnDataAvailable(nsIRequest *aRequest,
- nsISupports *aContext,
- nsIInputStream *aInputStream,
- uint64_t aOffset,
- uint32_t aCount)
-{
- MOZ_ASSERT_UNREACHABLE("This function should never ever be called");
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS(PackagedAppService::PackagedAppChannelListener, nsIStreamListener)
-
-NS_IMETHODIMP
-PackagedAppService::PackagedAppChannelListener::OnStartRequest(nsIRequest *aRequest,
- nsISupports *aContext)
-{
- bool isFromCache = false;
- nsCOMPtr<nsICacheInfoChannel> cacheChan = do_QueryInterface(aRequest);
- if (cacheChan) {
- cacheChan->IsFromCache(&isFromCache);
- }
-
- mDownloader->SetIsFromCache(isFromCache);
- LOG_PAS(("[%p] Downloader isFromCache: %d\n", mDownloader.get(), isFromCache));
-
- // XXX: This is the place to suspend the channel, doom existing cache entries
- // for previous resources, and then resume the channel.
- return mListener->OnStartRequest(aRequest, aContext);
-}
-
-NS_IMETHODIMP
-PackagedAppService::PackagedAppChannelListener::OnStopRequest(nsIRequest *aRequest,
- nsISupports *aContext,
- nsresult aStatusCode)
-{
- return mListener->OnStopRequest(aRequest, aContext, aStatusCode);
-}
-
-NS_IMETHODIMP
-PackagedAppService::PackagedAppChannelListener::OnDataAvailable(nsIRequest *aRequest,
- nsISupports *aContext,
- nsIInputStream *aInputStream,
- uint64_t aOffset,
- uint32_t aCount)
-{
- return mListener->OnDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS(PackagedAppService::PackagedAppDownloader,
- nsIStreamListener,
- nsIPackagedAppVerifierListener)
-
-nsresult
-PackagedAppService::PackagedAppDownloader::Init(nsILoadContextInfo* aInfo,
- const nsCString& aKey,
- const nsACString& aPackageOrigin)
-{
- nsresult rv;
- nsCOMPtr<nsICacheStorageService> cacheStorageService =
- do_GetService("@mozilla.org/netwerk/cache-storage-service;1", &rv);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- rv = cacheStorageService->DiskCacheStorage(aInfo, false,
- getter_AddRefs(mCacheStorage));
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- mPackageKey = aKey;
- mPackageOrigin = aPackageOrigin;
- mProcessingFirstRequest = true;
-
- return NS_OK;
-}
-
-void
-PackagedAppService::PackagedAppDownloader::EnsureVerifier(nsIRequest *aRequest)
-{
- if (mVerifier) {
- return;
- }
-
- LOG_PAS(("Creating PackagedAppVerifier."));
-
- nsCOMPtr<nsIMultiPartChannel> multiChannel(do_QueryInterface(aRequest));
- nsCString signature = GetSignatureFromChannel(multiChannel);
- nsCOMPtr<nsICacheEntry> packageCacheEntry = GetPackageCacheEntry(aRequest);
-
- mVerifier = new PackagedAppVerifier(this,
- mPackageOrigin,
- signature,
- packageCacheEntry);
-}
-
-NS_IMETHODIMP
-PackagedAppService::PackagedAppDownloader::OnStartRequest(nsIRequest *aRequest,
- nsISupports *aContext)
-{
- // In case an error occurs in this method mWriter should be null
- // so we don't accidentally write to the previous resource's cache entry.
- mWriter = nullptr;
-
- nsCOMPtr<nsIURI> uri;
- nsresult rv = GetSubresourceURI(aRequest, getter_AddRefs(uri));
-
- LogURI("PackagedAppDownloader::OnStartRequest", this, uri);
-
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return NS_OK;
- }
-
- rv = CacheEntryWriter::Create(uri, mCacheStorage, getter_AddRefs(mWriter));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return NS_OK;
- }
-
- MOZ_ASSERT(mWriter);
- rv = mWriter->OnStartRequest(aRequest, aContext);
- NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "OnStartRequest failed");
-
- EnsureVerifier(aRequest);
-
- if (!mVerifier->WouldVerify()) {
- // It means there's no signature or the signed app is disabled.
- return NS_OK;
- }
-
- mVerifier->OnStartRequest(nullptr, uri);
-
- // Since the header is considered as a part of the streaming data,
- // we need to feed the header as data to the verifier.
- nsCString header;
- if (!GetOriginalResponseHeader(aRequest, header)) {
- return NS_ERROR_FAILURE;
- }
- nsCOMPtr<nsIInputStream> stream = CreateSharedStringStream(header.get(), header.Length());
- return mVerifier->OnDataAvailable(nullptr, nullptr, stream, 0, header.Length());
-}
-
-nsresult
-PackagedAppService::PackagedAppDownloader::GetSubresourceURI(nsIRequest * aRequest,
- nsIURI ** aResult)
-{
- nsresult rv;
- nsCOMPtr<nsIResponseHeadProvider> provider(do_QueryInterface(aRequest));
- nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
-
- if (NS_WARN_IF(!provider || !chan)) {
- return NS_ERROR_INVALID_ARG;
- }
-
- nsHttpResponseHead *responseHead = provider->GetResponseHead();
- if (NS_WARN_IF(!responseHead)) {
- return NS_ERROR_FAILURE;
- }
- nsAutoCString contentLocation;
- rv = responseHead->GetHeader(nsHttp::ResolveAtom("Content-Location"), contentLocation);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- nsCOMPtr<nsIURI> uri;
- rv = chan->GetURI(getter_AddRefs(uri));
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- nsAutoCString path;
- rv = uri->GetPath(path);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- path += PACKAGED_APP_TOKEN;
-
- {
- // We use this temp URI to generate a path that is relative
- // to the package URI and not to the root of the domain.
- nsCOMPtr<nsIURI> tempURI;
- NS_NewURI(getter_AddRefs(tempURI), "http://temp-domain.local/");
- tempURI->SetPath(contentLocation);
- // The path is now normalized.
- tempURI->GetPath(contentLocation);
- // Remove the leading slash.
- contentLocation = Substring(contentLocation, 1);
- }
-
- path += contentLocation;
-
- nsCOMPtr<nsIURI> partURI;
- rv = uri->CloneIgnoringRef(getter_AddRefs(partURI));
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- rv = partURI->SetPath(path);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- partURI.forget(aResult);
- return NS_OK;
-}
-
-void
-PackagedAppService::PackagedAppDownloader::OnError(EErrorType aError)
-{
- // TODO: Handler verification error properly.
- LOG_PAS(("PackagedAppDownloader::OnError > %d", aError));
-
- FinalizeDownload(NS_ERROR_SIGNED_APP_MANIFEST_INVALID);
-}
-
-void
-PackagedAppService::PackagedAppDownloader::FinalizeDownload(nsresult aStatusCode)
-{
- // If this is the last part of the package, it means the requested resources
- // have not been found in the package so we return an appropriate error.
- // If the package response comes from the cache, we want to preserve the
- // statusCode, so ClearCallbacks looks for the resource in the cache, instead
- // of returning NS_ERROR_FILE_NOT_FOUND.
- if (NS_SUCCEEDED(aStatusCode) && !mIsFromCache) {
- aStatusCode = NS_ERROR_FILE_NOT_FOUND;
- }
-
- RefPtr<PackagedAppDownloader> kungFuDeathGrip(this);
- // NotifyPackageDownloaded removes the ref from the array. Keep a temp ref
- if (gPackagedAppService) {
- gPackagedAppService->NotifyPackageDownloaded(mPackageKey);
- }
- ClearCallbacks(aStatusCode);
-
- // Explicity remove the downloader from the verifier. The downloader
- // will die after exiting this function but the verifier may still be
- // alive for a while since some resources maybe being verified.
- if (mVerifier) {
- mVerifier->ClearListener();
- }
-}
-
-nsCString
-PackagedAppService::PackagedAppDownloader::GetSignatureFromChannel(nsIMultiPartChannel* aMulitChannel)
-{
- if (mIsFromCache) {
- // We don't need the signature if the resource is loaded from cache.
- return EmptyCString();
- }
-
- if (!aMulitChannel) {
- LOG_PAS(("The package is either not loaded from cache or malformed."));
- return EmptyCString();
- }
-
- nsCString packageHeader;
- aMulitChannel->GetPreamble(packageHeader);
-
- return packageHeader;
-}
-
-NS_IMETHODIMP
-PackagedAppService::PackagedAppDownloader::OnStopRequest(nsIRequest *aRequest,
- nsISupports *aContext,
- nsresult aStatusCode)
-{
- nsCOMPtr<nsIMultiPartChannel> multiChannel(do_QueryInterface(aRequest));
- nsresult rv;
-
- LOG_PAS(("[%p] PackagedAppDownloader::OnStopRequest > status:%X multiChannel:%p\n",
- this, aStatusCode, multiChannel.get()));
-
- mProcessingFirstRequest = false;
-
- // lastPart will be true if this is the last part in the package,
- // or if aRequest isn't a multipart channel
- bool lastPart = true;
- if (multiChannel) {
- multiChannel->GetIsLastPart(&lastPart);
- }
-
- // The request is normally a multiPartChannel. If it isn't, it generally means
- // an error has occurred in nsMultiMixedConv.
- // If an error occurred in OnStartRequest, mWriter could be null.
- if (!multiChannel || !mWriter) {
- LOG_PAS(("Either the package was loaded from cache or malformed"));
- if (lastPart) {
- // Chances to get here:
- // 1) Very likely the package has been cached or
- // 2) Less likely the package is malformed.
- if (!mVerifier || !mVerifier->WouldVerify()) {
- FinalizeDownload(aStatusCode);
- } else {
- // We've got a broken last part and some resources might be still
- // in the verification queue. Send a dummy ResourceCacheInfo to the
- // verifier so this broken resource will be processed in the correct
- // order.
- mVerifier->SetHasBrokenLastPart(aStatusCode);
- }
- }
- return NS_OK;
- }
-
- LOG_PAS(("We are going to finish the resource and process it in the verifier."));
-
- // We've got a resource downloaded. Finalize this resource cache and delegate to
- // PackagedAppVerifier rather than serving this resource right away.
- mWriter->OnStopRequest(aRequest, aContext, aStatusCode);
-
- nsCOMPtr<nsIURI> uri;
- rv = GetSubresourceURI(aRequest, getter_AddRefs(uri));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return NS_OK;
- }
-
- nsCOMPtr<nsICacheEntry> entry;
- mWriter->mEntry.swap(entry);
-
- // We don't need the writer anymore - this will close its stream
- mWriter = nullptr;
-
- // The downloader only needs to focus on PackagedAppVerifierListener callback.
- // The PackagedAppVerifier would handle the manifest/resource verification.
- RefPtr<ResourceCacheInfo> info =
- new ResourceCacheInfo(uri, entry, aStatusCode, lastPart);
-
- if (!mVerifier->WouldVerify()) {
- // No manifest at all. Everything is simply a resource.
- OnResourceVerified(info, true);
- return NS_OK;
- }
-
- mVerifier->OnStopRequest(nullptr, info, aStatusCode);
-
- return NS_OK;
-}
-
-nsresult
-PackagedAppService::PackagedAppDownloader::ConsumeData(nsIInputStream *aStream,
- void *aClosure,
- const char *aFromRawSegment,
- uint32_t aToOffset,
- uint32_t aCount,
- uint32_t *aWriteCount)
-{
- MOZ_ASSERT(aClosure, "The closure must not be null");
-
- if (!aStream) {
- return NS_ERROR_INVALID_ARG;
- }
-
- PackagedAppDownloader *self = static_cast<PackagedAppDownloader*>(aClosure);
-
- if (!self->mWriter) {
- *aWriteCount = aCount;
- return NS_OK;
- }
-
- self->mWriter->ConsumeData(aFromRawSegment, aCount, aWriteCount);
-
- if (!self->mVerifier->WouldVerify()) {
- // No signature or signed app support is disabled.
- return NS_OK;
- }
-
- if (self->mProcessingFirstRequest) {
- // mProcessingFirstRequest will be set to false on the first OnStopRequest.
- self->mManifestContent.Append(aFromRawSegment, aCount);
- }
-
- nsCOMPtr<nsIInputStream> stream = CreateSharedStringStream(aFromRawSegment, aCount);
- return self->mVerifier->OnDataAvailable(nullptr, nullptr, stream, 0, aCount);
-}
-
-NS_IMETHODIMP
-PackagedAppService::PackagedAppDownloader::OnDataAvailable(nsIRequest *aRequest,
- nsISupports *aContext,
- nsIInputStream *aInputStream,
- uint64_t aOffset,
- uint32_t aCount)
-{
- uint32_t n;
- return aInputStream->ReadSegments(ConsumeData, this, aCount, &n);
-}
-
-nsresult
-PackagedAppService::PackagedAppDownloader::AddCallback(nsIURI *aURI,
- nsICacheEntryOpenCallback *aCallback)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "mCallbacks hashtable is not thread safe");
- nsAutoCString spec;
- aURI->GetSpecIgnoringRef(spec);
-
- LogURI("PackagedAppDownloader::AddCallback", this, aURI);
- LOG_PAS(("[%p] > callback: %p\n", this, aCallback));
-
- // Check if we already have a resource waiting for this resource
- nsCOMArray<nsICacheEntryOpenCallback>* array = mCallbacks.Get(spec);
- if (array) {
- if (array->Length() == 0) {
- // The download of this resource has already completed, hence we don't
- // need to wait for it to be inserted in the cache and we can serve it
- // right now, directly. See also the CallCallbacks method bellow.
- LOG_PAS(("[%p] > already downloaded\n", this));
-
- mCacheStorage->AsyncOpenURI(aURI, EmptyCString(),
- nsICacheStorage::OPEN_READONLY, aCallback);
- } else {
- LOG_PAS(("[%p] > adding to array\n", this));
- // Add this resource to the callback array
- array->AppendObject(aCallback);
- }
- } else {
- LOG_PAS(("[%p] > creating array\n", this));
- // This is the first callback for this URI.
- // Create a new array and add the callback
- nsCOMArray<nsICacheEntryOpenCallback>* newArray =
- new nsCOMArray<nsICacheEntryOpenCallback>();
- newArray->AppendObject(aCallback);
- mCallbacks.Put(spec, newArray);
- }
-
- return NS_OK;
-}
-
-nsresult
-PackagedAppService::PackagedAppDownloader::CallCallbacks(nsIURI *aURI,
- nsICacheEntry *aEntry,
- nsresult aResult)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "mCallbacks hashtable is not thread safe");
- // Hold on to this entry while calling the callbacks
- nsCOMPtr<nsICacheEntry> handle(aEntry);
-
- LogURI("PackagedAppService::PackagedAppDownloader::CallCallbacks", this, aURI);
- LOG_PAS(("[%p] > status:%X\n", this, aResult));
-
- nsAutoCString spec;
- aURI->GetAsciiSpec(spec);
-
- nsCOMArray<nsICacheEntryOpenCallback>* array = mCallbacks.Get(spec);
- if (array) {
- uint32_t callbacksNum = array->Length();
- // Call all the callbacks for this URI
- for (uint32_t i = 0; i < array->Length(); ++i) {
- nsCOMPtr<nsICacheEntryOpenCallback> callback(array->ObjectAt(i));
- // We call to AsyncOpenURI which automatically calls the callback.
- mCacheStorage->AsyncOpenURI(aURI, EmptyCString(),
- nsICacheStorage::OPEN_READONLY, callback);
- }
- // Clear the array but leave it in the hashtable
- // An empty array means that the resource was already downloaded, and a
- // new call to AddCallback can simply return it from the cache.
- array->Clear();
- LOG_PAS(("[%p] > called callbacks (%d)\n", this, callbacksNum));
- } else {
- // There were no listeners waiting for this resource, but we insert a new
- // empty array into the hashtable so if any new callbacks are added while
- // downloading the package, we can simply return it from the cache.
- nsCOMArray<nsICacheEntryOpenCallback>* newArray =
- new nsCOMArray<nsICacheEntryOpenCallback>();
- mCallbacks.Put(spec, newArray);
- LOG_PAS(("[%p] > created array\n", this));
- }
-
- aEntry->ForceValidFor(0);
- return NS_OK;
-}
-
-nsresult
-PackagedAppService::PackagedAppDownloader::ClearCallbacks(nsresult aResult)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "mCallbacks hashtable is not thread safe");
- LOG_PAS(("[%p] PackagedAppService::PackagedAppDownloader::ClearCallbacks > packageKey:%s status:%X\n",
- this, mPackageKey.get(), aResult));
-
- // Clear the registered callbacks which are not called at all. If the package is already
- // in the cache, the requested resource will be called back here.
- for (auto iter = mCallbacks.Iter(); !iter.Done(); iter.Next()) {
- const nsACString& key = iter.Key();
- const nsCOMArray<nsICacheEntryOpenCallback>* callbackArray = iter.UserData();
-
- if (NS_SUCCEEDED(aResult)) {
- // For success conditions we try to open the cache entry.
- // This can occur when the package metadata is served from the cache,
- // as it hasn't changed, but the entries are still in the cache.
- nsCOMPtr<nsIURI> uri;
- DebugOnly<nsresult> rv = NS_NewURI(getter_AddRefs(uri), key);
- MOZ_ASSERT(NS_SUCCEEDED(rv));
-
- LOG_PAS(("[%p] > calling AsyncOpenURI for %s\n", this, key.BeginReading()));
- for (uint32_t i = 0; i < callbackArray->Length(); ++i) {
- nsCOMPtr<nsICacheEntryOpenCallback> callback = callbackArray->ObjectAt(i);
- mCacheStorage->AsyncOpenURI(uri, EmptyCString(),
- nsICacheStorage::OPEN_READONLY, callback);
- }
-
- } else { // an error has occured
- // We just call all the callbacks and pass the error result
- LOG_PAS(("[%p] > passing NULL cache entry for %s\n", this, key.BeginReading()));
- for (uint32_t i = 0; i < callbackArray->Length(); ++i) {
- nsCOMPtr<nsICacheEntryOpenCallback> callback = callbackArray->ObjectAt(i);
- callback->OnCacheEntryAvailable(nullptr, false, nullptr, aResult);
- }
- }
-
- // Finally, we remove this entry from the hashtable.
- iter.Remove();
- }
-
- return NS_OK;
-}
-
-static bool
-AddPackageIdToOrigin(nsACString& aOrigin, const nsACString& aPackageId)
-{
- nsAutoCString originNoSuffix;
- mozilla::NeckoOriginAttributes attrs;
- if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
- return false;
- }
-
- attrs.mSignedPkg = NS_ConvertUTF8toUTF16(aPackageId);
- nsAutoCString suffixWithPackageId;
- attrs.CreateSuffix(suffixWithPackageId);
- aOrigin = originNoSuffix + suffixWithPackageId;
- return true;
-}
-
-void
-PackagedAppService::PackagedAppDownloader::InstallSignedPackagedApp(const ResourceCacheInfo* aInfo)
-{
- // TODO: Bug 1178533 to register permissions, system messages etc on navigation to
- // signed packages.
- LOG_PAS(("Install this packaged app."));
- bool isSuccess = false;
-
- nsCOMPtr<nsIInstallPackagedWebapp> installer =
- do_GetService("@mozilla.org/newapps/installpackagedwebapp;1");
-
- if (!installer) {
- LOG_PAS(("InstallSignedPackagedApp: fail to get InstallPackagedWebapp service"));
- return OnError(ERROR_GET_INSTALLER_FAILED);
- }
-
- nsCString manifestURL;
- aInfo->mURI->GetAsciiSpec(manifestURL);
-
-
- nsCString originWithPackageId = mPackageOrigin;
- if (!AddPackageIdToOrigin(originWithPackageId, mVerifier->GetPackageIdentifier())) {
- NS_WARNING("mPackageOrigin is malformed.");
- }
-
- installer->InstallPackagedWebapp(mManifestContent.get(),
- originWithPackageId.get(),
- manifestURL.get(),
- &isSuccess);
- if (!isSuccess) {
- LOG_PAS(("InstallSignedPackagedApp: failed to install permissions"));
- return OnError(ERROR_INSTALL_RESOURCE_FAILED);
- }
-
- LOG_PAS(("InstallSignedPackagedApp: success."));
-}
-
-//------------------------------------------------------------------
-// nsIPackagedAppVerifierListener
-//------------------------------------------------------------------
-NS_IMETHODIMP
-PackagedAppService::PackagedAppDownloader::OnVerified(bool aIsManifest,
- nsIURI* aUri,
- nsICacheEntry* aCacheEntry,
- nsresult aStatusCode,
- bool aIsLastPart,
- bool aVerificationSuccess)
-{
- if (!aUri) {
- NS_WARNING("We've got a broken last part.");
- FinalizeDownload(aStatusCode);
- return NS_OK;
- }
-
- RefPtr<ResourceCacheInfo> info =
- new ResourceCacheInfo(aUri, aCacheEntry, aStatusCode, aIsLastPart);
-
- aIsManifest ? OnManifestVerified(info, aVerificationSuccess)
- : OnResourceVerified(info, aVerificationSuccess);
-
- return NS_OK;
-}
-
-void
-PackagedAppService::PackagedAppDownloader::OnManifestVerified(const ResourceCacheInfo* aInfo,
- bool aSuccess)
-{
- if (!aSuccess) {
- // The signature is found but not verified.
- return OnError(ERROR_MANIFEST_VERIFIED_FAILED);
- }
-
- // TODO: If we disallow the request for the manifest file, do NOT callback here.
- CallCallbacks(aInfo->mURI, aInfo->mCacheEntry, aInfo->mStatusCode);
-
- if (aInfo->mIsLastPart) {
- NS_WARNING("This package has manifest only.");
- FinalizeDownload(aInfo->mStatusCode);
- return;
- }
-
- bool isPackagedSigned;
- mVerifier->GetIsPackageSigned(&isPackagedSigned);
- if (!isPackagedSigned) {
- // A verified but unsigned manifest means this package has no signature.
- LOG_PAS(("No signature in the package. Just run normally."));
- return;
- }
-
- InstallSignedPackagedApp(aInfo);
-}
-
-void
-PackagedAppService::PackagedAppDownloader::OnResourceVerified(const ResourceCacheInfo* aInfo,
- bool aSuccess)
-{
- if (!aSuccess) {
- return OnError(ERROR_RESOURCE_VERIFIED_FAILED);
- }
-
- // Serve this resource to all listeners.
- CallCallbacks(aInfo->mURI, aInfo->mCacheEntry, aInfo->mStatusCode);
-
- if (aInfo->mIsLastPart) {
- LOG_PAS(("This is the last part. FinalizeDownload (%d)", aInfo->mStatusCode));
- FinalizeDownload(aInfo->mStatusCode);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-PackagedAppService::PackagedAppService()
-{
- gPackagedAppService = this;
- LOG_PAS(("[%p] Created PackagedAppService\n", this));
-}
-
-PackagedAppService::~PackagedAppService()
-{
- LOG_PAS(("[%p] Destroying PackagedAppService\n", this));
- gPackagedAppService = nullptr;
-}
-
-/* static */ nsresult
-PackagedAppService::GetPackageURI(nsIURI *aURI, nsIURI **aPackageURI)
-{
- nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
- if (!url) {
- return NS_ERROR_INVALID_ARG;
- }
-
- nsAutoCString path;
- nsresult rv = url->GetFilePath(path);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- int32_t pos = path.Find(PACKAGED_APP_TOKEN);
- if (pos == kNotFound) {
- return NS_ERROR_INVALID_ARG;
- }
-
- nsCOMPtr<nsIURI> packageURI;
- rv = aURI->CloneIgnoringRef(getter_AddRefs(packageURI));
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- rv = packageURI->SetPath(Substring(path, 0, pos));
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- packageURI.forget(aPackageURI);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-PackagedAppService::GetResource(nsIChannel *aChannel,
- nsICacheEntryOpenCallback *aCallback)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "mDownloadingPackages hashtable is not thread safe");
- LOG_PAS(("[%p] PackagedAppService::GetResource(aChannel: %p, aCallback: %p)\n",
- this, aChannel, aCallback));
-
- if (!aChannel || !aCallback) {
- return NS_ERROR_INVALID_ARG;
- }
-
- nsresult rv;
- nsIScriptSecurityManager *securityManager =
- nsContentUtils::GetSecurityManager();
- if (!securityManager) {
- LOG_PAS(("[%p] > No securityManager\n", this));
- return NS_ERROR_UNEXPECTED;
- }
- nsCOMPtr<nsIPrincipal> principal;
- rv = securityManager->GetChannelURIPrincipal(aChannel, getter_AddRefs(principal));
- if (NS_FAILED(rv) || !principal) {
- LOG_PAS(("[%p] > Error getting principal rv=%X principal=%p\n",
- this, rv, principal.get()));
- return NS_FAILED(rv) ? rv : NS_ERROR_NULL_POINTER;
- }
-
- nsCOMPtr<nsILoadContextInfo> loadContextInfo = GetLoadContextInfo(aChannel);
- if (!loadContextInfo) {
- LOG_PAS(("[%p] > Channel has no loadContextInfo\n", this));
- return NS_ERROR_NULL_POINTER;
- }
-
- nsLoadFlags loadFlags = 0;
- rv = aChannel->GetLoadFlags(&loadFlags);
- if (NS_FAILED(rv)) {
- LOG_PAS(("[%p] > Error calling GetLoadFlags rv=%X\n", this, rv));
- return rv;
- }
-
- nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
-
- nsCOMPtr<nsIURI> uri;
- rv = aChannel->GetURI(getter_AddRefs(uri));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- LOG_PAS(("[%p] > Error calling GetURI rv=%X\n", this, rv));
- return rv;
- }
-
- LogURI("PackagedAppService::GetResource", this, uri, loadContextInfo);
- nsCOMPtr<nsIURI> packageURI;
- rv = GetPackageURI(uri, getter_AddRefs(packageURI));
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- nsAutoCString key;
- CacheFileUtils::AppendKeyPrefix(loadContextInfo, key);
-
- {
- nsAutoCString spec;
- packageURI->GetAsciiSpec(spec);
- key += ":";
- key += spec;
- }
-
- RefPtr<PackagedAppDownloader> downloader;
- if (mDownloadingPackages.Get(key, getter_AddRefs(downloader))) {
- // We have determined that the file is not in the cache.
- // If we find that the package that the file belongs to is currently being
- // downloaded, we will add the callback to the package's queue, and it will
- // be called once the file is processed and saved in the cache.
- downloader->AddCallback(uri, aCallback);
- return NS_OK;
- }
-
- nsCOMPtr<nsIChannel> channel;
- rv = NS_NewChannelInternal(
- getter_AddRefs(channel), packageURI,
- loadInfo,
- nullptr, nullptr, loadFlags);
-
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- nsCOMPtr<nsICachingChannel> cacheChan(do_QueryInterface(channel));
- if (cacheChan) {
- // Each resource in the package will be put in its own cache entry
- // during the first load of the package, so we only want the channel to
- // cache the response head, not the entire content of the package.
- cacheChan->SetCacheOnlyMetadata(true);
- }
-
- downloader = new PackagedAppDownloader();
- nsCString packageOrigin;
- principal->GetOrigin(packageOrigin);
- rv = downloader->Init(loadContextInfo, key, packageOrigin);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- downloader->AddCallback(uri, aCallback);
-
- nsCOMPtr<nsIStreamConverterService> streamconv =
- do_GetService("@mozilla.org/streamConverters;1", &rv);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- nsCOMPtr<nsIStreamListener> mimeConverter;
- rv = streamconv->AsyncConvertData(APPLICATION_PACKAGE, "*/*", downloader, nullptr,
- getter_AddRefs(mimeConverter));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- // Add the package to the hashtable.
- mDownloadingPackages.Put(key, downloader);
-
- RefPtr<PackagedAppChannelListener> listener =
- new PackagedAppChannelListener(downloader, mimeConverter);
-
- nsCOMPtr<nsIInterfaceRequestor> loadContext;
- aChannel->GetNotificationCallbacks(getter_AddRefs(loadContext));
- if (loadContext) {
- channel->SetNotificationCallbacks(loadContext);
- }
- return NS_MaybeOpenChannelUsingAsyncOpen2(channel, listener);
-}
-
-nsresult
-PackagedAppService::NotifyPackageDownloaded(nsCString aKey)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "mDownloadingPackages hashtable is not thread safe");
- mDownloadingPackages.Remove(aKey);
- LOG_PAS(("[%p] PackagedAppService::NotifyPackageDownloaded > %s\n", this, aKey.get()));
- return NS_OK;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/http/PackagedAppService.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et 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_net_PackagedAppService_h
-#define mozilla_net_PackagedAppService_h
-
-#include "nsIPackagedAppService.h"
-#include "nsILoadContextInfo.h"
-#include "nsICacheStorage.h"
-#include "PackagedAppVerifier.h"
-#include "nsIMultiPartChannel.h"
-#include "PackagedAppVerifier.h"
-#include "nsCOMArray.h"
-#include "nsRefPtrHashtable.h"
-
-namespace mozilla {
-namespace net {
-
-class nsHttpResponseHead;
-
-// This service is used to download packages from the web.
-// Individual resources in the package are saved in the browser cache. It also
-// provides an interface to asynchronously request resources from packages,
-// which are either returned from the cache if they exist and are valid,
-// or downloads the package.
-// The package format is defined at:
-// https://w3ctag.github.io/packaging-on-the-web/#streamable-package-format
-// Downloading the package is triggered by calling getResource()
-class PackagedAppService final
- : public nsIPackagedAppService
-{
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSIPACKAGEDAPPSERVICE
-
- PackagedAppService();
-
-private:
- ~PackagedAppService();
-
- // Called by PackageAppDownloader once the download has finished
- // (or encountered an error) to remove the package from mDownloadingPackages
- // Should be called on the main thread.
- nsresult NotifyPackageDownloaded(nsCString aKey);
-
- // Extract the URI of a package from the given packaged resource URI.
- static nsresult GetPackageURI(nsIURI *aUri, nsIURI **aPackageURI);
-
- // This class is used to write data into the cache entry corresponding to the
- // packaged resource being downloaded.
- // The PackagedAppDownloader will hold a ref to a CacheEntryWriter that
- // corresponds to the entry that is currently being downloaded.
- class CacheEntryWriter final
- : public nsIStreamListener
- {
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSISTREAMLISTENER
- NS_DECL_NSIREQUESTOBSERVER
-
- // If successful, calling this static method will create a new
- // CacheEntryWriter and will create the cache entry associated to the
- // resource.
- static nsresult Create(nsIURI*, nsICacheStorage*, CacheEntryWriter**);
-
- nsCOMPtr<nsICacheEntry> mEntry;
-
- // Called by PackagedAppDownloader to write data to the cache entry.
- nsresult ConsumeData(const char *aBuf,
- uint32_t aCount,
- uint32_t *aWriteCount);
-
- private:
- CacheEntryWriter() { }
- ~CacheEntryWriter() { }
-
- // Copy the security-info metadata from the channel to the cache entry
- // so packaged resources can be accessed over https.
- nsresult CopySecurityInfo(nsIChannel *aChannel);
-
- // Copy headers that apply to all resources in the package
- static nsresult CopyHeadersFromChannel(nsIChannel *aChannel,
- nsHttpResponseHead *aHead);
-
- // We write the data we read from the network into this stream which goes
- // to the cache entry.
- nsCOMPtr<nsIOutputStream> mOutputStream;
- };
-
- // This class is used to download a packaged app. It acts as a listener
- // for the nsMultiMixedConv object that parses the package.
- // There is an OnStartRequest, OnDataAvailable*, OnStopRequest sequence called
- // for each resource
- // The PackagedAppService holds a hash-table of the PackagedAppDownloaders
- // that are in progress to coalesce same loads.
- // Once the downloading is completed, it should call
- // NotifyPackageDownloaded(packageURI), so the service releases the ref.
- class PackagedAppDownloader final
- : public nsIStreamListener
- , public nsIPackagedAppVerifierListener
- {
- public:
- typedef PackagedAppVerifier::ResourceCacheInfo ResourceCacheInfo;
-
- private:
- enum EErrorType {
- ERROR_MANIFEST_VERIFIED_FAILED,
- ERROR_RESOURCE_VERIFIED_FAILED,
- ERROR_GET_INSTALLER_FAILED,
- ERROR_INSTALL_RESOURCE_FAILED,
- };
-
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSISTREAMLISTENER
- NS_DECL_NSIREQUESTOBSERVER
- NS_DECL_NSIPACKAGEDAPPVERIFIERLISTENER
-
- // Initializes mCacheStorage and saves aKey as mPackageKey which is later
- // used to remove this object from PackagedAppService::mDownloadingPackages
- // - aKey is a string which uniquely identifies this package within the
- // packagedAppService
- nsresult Init(nsILoadContextInfo* aInfo, const nsCString &aKey,
- const nsACString& aPackageOrigin);
- // Registers a callback which gets called when the given nsIURI is downloaded
- // aURI is the full URI of a subresource, composed of packageURI + !// + subresourcePath
- // aRequester is the outer channel who makes the request for aURI.
- nsresult AddCallback(nsIURI *aURI,
- nsICacheEntryOpenCallback *aCallback);
-
- // Remove the callback from the resource callback list.
- nsresult RemoveCallbacks(nsICacheEntryOpenCallback* aCallback);
-
- // Called by PackagedAppChannelListener to note the fact that the package
- // is coming from the cache, and no subresources are to be expected as only
- // package metadata is saved in the cache.
- void SetIsFromCache(bool aFromCache) { mIsFromCache = aFromCache; }
-
- // Notify the observers who are interested in knowing a signed packaged content
- // is about to load from either HTTP or cache..
- void NotifyOnStartSignedPackageRequest(const nsACString& PackageOrigin);
-
- private:
- ~PackagedAppDownloader() { }
-
- // Static method used to write data into the cache entry or discard
- // if there's no writer. Used as a writer function of
- // nsIInputStream::ReadSegments.
- static nsresult ConsumeData(nsIInputStream *aStream,
- void *aClosure,
- const char *aFromRawSegment,
- uint32_t aToOffset,
- uint32_t aCount,
- uint32_t *aWriteCount);
-
- //---------------------------------------------------------------
- // For PackagedAppVerifierListener.
- //---------------------------------------------------------------
- virtual void OnManifestVerified(const ResourceCacheInfo* aInfo, bool aSuccess);
- virtual void OnResourceVerified(const ResourceCacheInfo* aInfo, bool aSuccess);
-
- // Handle all kinds of error during package downloading.
- void OnError(EErrorType aError);
-
- // Called when the last part is complete or the resource is from cache.
- void FinalizeDownload(nsresult aStatusCode);
-
- // Get the signature from the multipart channel.
- nsCString GetSignatureFromChannel(nsIMultiPartChannel* aChannel);
-
- // Start off a resource hash computation and feed the HTTP response header.
- nsresult BeginHashComputation(nsIURI* aURI, nsIRequest* aRequest);
-
- // Ensure a packaged app verifier is created.
- void EnsureVerifier(nsIRequest *aRequest);
-
- // Handle all tasks about app installation like permission and system message
- // registration.
- void InstallSignedPackagedApp(const ResourceCacheInfo* aInfo);
-
- // Calls all the callbacks registered for the given URI.
- // aURI is the full URI of a subresource, composed of packageURI + !// + subresourcePath
- // It passes the cache entry and the result when calling OnCacheEntryAvailable
- nsresult CallCallbacks(nsIURI *aURI, nsICacheEntry *aEntry, nsresult aResult);
- // Clears all the callbacks for this package
- // This would get called at the end of downloading the package and would
- // cause us to call OnCacheEntryAvailable with a null entry. This would be
- // equivalent to a 404 when loading from the net.
- nsresult ClearCallbacks(nsresult aResult);
- // Returns a URI with the subresource's full URI
- // The request must be QIable to nsIResponseHeadProvider since it looks
- // at the Content-Location header to compute the full path.
- static nsresult GetSubresourceURI(nsIRequest * aRequest, nsIURI **aResult);
- // Used to write data into the cache entry of the resource currently being
- // downloaded. It is kept alive until the downloader receives OnStopRequest
- RefPtr<CacheEntryWriter> mWriter;
- // Cached value of nsICacheStorage
- nsCOMPtr<nsICacheStorage> mCacheStorage;
- // A hastable containing all the consumers which requested a resource and need
- // to be notified once it is inserted into the cache.
- // The key is a subresource URI - http://example.com/package.pak!//res.html
- // Should only be used on the main thread.
- nsClassHashtable<nsCStringHashKey, nsCOMArray<nsICacheEntryOpenCallback>> mCallbacks;
- // The key with which this package is inserted in
- // PackagedAppService::mDownloadingPackages
- nsCString mPackageKey;
-
- // Whether the package is from the cache
- bool mIsFromCache;
-
- // Deal with verification and delegate callbacks to the downloader.
- RefPtr<PackagedAppVerifier> mVerifier;
-
- // The package origin without signed package origin identifier.
- // If you need the origin with the signity taken into account, use
- // PackagedAppVerifier::GetPackageOrigin().
- nsCString mPackageOrigin;
-
- //The app id of the package loaded from the LoadContextInfo
- uint32_t mAppId;
-
- // A flag to indicate if we are processing the first request.
- bool mProcessingFirstRequest;
-
- // A in-memory copy of the manifest content.
- nsCString mManifestContent;
- };
-
- // Intercepts OnStartRequest, OnDataAvailable*, OnStopRequest method calls
- // and forwards them to the listener.
- // The target is a `mListener` which converts the package to individual
- // resources and serves them to mDownloader.
- // This class is able to perform conditional actions based on whether the
- // underlying nsIHttpChannel is served from the cache.
- // As this object serves as a listener for the channel, it is kept alive until
- // calling OnStopRequest is completed.
- class PackagedAppChannelListener final
- : public nsIStreamListener
- {
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSISTREAMLISTENER
- NS_DECL_NSIREQUESTOBSERVER
-
- PackagedAppChannelListener(PackagedAppDownloader *aDownloader,
- nsIStreamListener *aListener)
- : mDownloader(aDownloader)
- , mListener(aListener)
- {
- }
- private:
- ~PackagedAppChannelListener() { }
-
- RefPtr<PackagedAppDownloader> mDownloader;
- nsCOMPtr<nsIStreamListener> mListener; // nsMultiMixedConv
- };
-
- // A hashtable of packages that are currently being downloaded.
- // The key is a string formed by concatenating LoadContextInfo and package URI
- // Should only be used on the main thread.
- nsRefPtrHashtable<nsCStringHashKey, PackagedAppDownloader> mDownloadingPackages;
-};
-
-
-} // namespace net
-} // namespace mozilla
-
-#endif // mozilla_net_PackagedAppService_h
deleted file mode 100644
--- a/netwerk/protocol/http/PackagedAppUtils.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-'use strict';
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const PACKAGEDAPPUTILS_CONTRACTID = "@mozilla.org/network/packaged-app-utils;1";
-const PACKAGEDAPPUTILS_CID = Components.ID("{fe8f1c2e-3c13-11e5-9a3f-bbf47d1e6697}");
-
-function PackagedAppUtils() {
- this.packageIdentifier = '';
- this.packageOrigin = '';
-}
-
-var DEBUG = 0
-function debug(s) {
- if (DEBUG) {
- dump("-*- PackagedAppUtils: " + s + "\n");
- }
-}
-
-PackagedAppUtils.prototype = {
- classID: PACKAGEDAPPUTILS_CID,
- contractID: PACKAGEDAPPUTILS_CONTRACTID,
- classDescription: "Packaged App Utils",
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIPackagedAppUtils]),
-
- verifyManifest: function(aHeader, aManifest, aCallback, aDeveloperMode) {
- debug("Manifest: " + aManifest);
-
- // parse signature from header
- let signature;
- const signatureField = "manifest-signature: ";
- for (let item of aHeader.split('\r\n')) {
- if (item.substr(0, signatureField.length) == signatureField) {
- signature = item.substr(signatureField.length);
- break;
- }
- }
- if (!signature) {
- debug("No signature in header");
- aCallback.fireVerifiedEvent(true, false);
- return;
- }
- debug("Signature: " + signature);
-
- try {
- // Remove header
- let manifestBody = aManifest.substr(aManifest.indexOf('\r\n\r\n') + 4);
- debug("manifestBody: " + manifestBody);
-
- // Parse manifest, store resource hashes
- let manifestObj = JSON.parse(manifestBody);
- this.packageIdentifier = manifestObj["package-identifier"];
- this.packageOrigin = manifestObj["moz-package-origin"];
- this.resources = manifestObj["moz-resources"];
-
- // Base64 decode
- signature = atob(signature);
- } catch (e) {
- debug("Manifest parsing failure");
- aCallback.fireVerifiedEvent(true, false);
- return;
- }
-
- let manifestStream = Cc["@mozilla.org/io/string-input-stream;1"]
- .createInstance(Ci.nsIStringInputStream);
- let signatureStream = Cc["@mozilla.org/io/string-input-stream;1"]
- .createInstance(Ci.nsIStringInputStream);
- manifestStream.setData(aManifest, aManifest.length);
- signatureStream.setData(signature, signature.length);
-
- let certDb;
- try {
- certDb = Cc["@mozilla.org/security/x509certdb;1"]
- .getService(Ci.nsIX509CertDB);
- } catch (e) {
- debug("nsIX509CertDB error: " + e);
- // unrecoverable error, don't bug the user
- throw "CERTDB_ERROR";
- }
-
- let trustedRoot = aDeveloperMode ? Ci.nsIX509CertDB.DeveloperImportedRoot
- : Ci.nsIX509CertDB.PrivilegedPackageRoot;
-
- certDb.verifySignedManifestAsync(trustedRoot, manifestStream, signatureStream,
- function(aRv, aCert) {
- aCallback.fireVerifiedEvent(true, Components.isSuccessCode(aRv));
- });
- },
-
- checkIntegrity: function(aFileName, aHashValue, aCallback) {
- debug("checkIntegrity() " + aFileName + ": " + aHashValue + "\n");
- if (!this.resources) {
- debug("resource hashes not found");
- aCallback.fireVerifiedEvent(false, false);
- return;
- }
- for (let r of this.resources) {
- if (r.src === aFileName) {
- debug("found integrity = " + r.integrity);
- aCallback.fireVerifiedEvent(false, r.integrity === aHashValue);
- return;
- }
- }
- aCallback.fireVerifiedEvent(false, false);
- },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PackagedAppUtils]);
deleted file mode 100644
--- a/netwerk/protocol/http/PackagedAppUtils.manifest
+++ /dev/null
@@ -1,3 +0,0 @@
-# PackagedAppUtils.js
-component {fe8f1c2e-3c13-11e5-9a3f-bbf47d1e6697} PackagedAppUtils.js
-contract @mozilla.org/network/packaged-app-utils;1 {fe8f1c2e-3c13-11e5-9a3f-bbf47d1e6697}
deleted file mode 100644
--- a/netwerk/protocol/http/PackagedAppVerifier.cpp
+++ /dev/null
@@ -1,496 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et 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 "nsICacheStorage.h"
-#include "nsICacheStorageService.h"
-#include "../../cache2/CacheFileUtils.h"
-#include "mozilla/Logging.h"
-#include "mozilla/DebugOnly.h"
-#include "nsThreadUtils.h"
-#include "PackagedAppVerifier.h"
-#include "nsITimer.h"
-#include "nsIPackagedAppVerifier.h"
-#include "mozilla/Preferences.h"
-#include "nsIPackagedAppUtils.h"
-#include "nsIInputStream.h"
-#include "nsComponentManagerUtils.h"
-#include "nsIURL.h"
-#include "mozilla/BasePrincipal.h"
-#include "HttpLog.h"
-
-static const short kResourceHashType = nsICryptoHash::SHA256;
-
-static bool gSignedAppEnabled = false;
-
-namespace mozilla {
-namespace net {
-
-///////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS(PackagedAppVerifier, nsIPackagedAppVerifier, nsIVerificationCallback)
-
-NS_IMPL_ISUPPORTS(PackagedAppVerifier::ResourceCacheInfo, nsISupports)
-
-const char* PackagedAppVerifier::kSignedPakIdMetadataKey = "package-id";
-
-PackagedAppVerifier::PackagedAppVerifier()
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(),
- "PackagedAppVerifier::OnResourceVerified must be on main thread");
-
- Init(nullptr, EmptyCString(), EmptyCString(), nullptr);
-}
-
-PackagedAppVerifier::PackagedAppVerifier(nsIPackagedAppVerifierListener* aListener,
- const nsACString& aPackageOrigin,
- const nsACString& aSignature,
- nsICacheEntry* aPackageCacheEntry)
-{
- Init(aListener, aPackageOrigin, aSignature, aPackageCacheEntry);
-}
-
-PackagedAppVerifier::~PackagedAppVerifier()
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "mPendingResourceCacheInfoList is not thread safe.");
- while (auto i = mPendingResourceCacheInfoList.popFirst()) {
- // This seems to be the only way that we can manually delete a
- // nsISupports instance with no warning.
- RefPtr<ResourceCacheInfo> deleter(i);
- }
-}
-
-NS_IMETHODIMP PackagedAppVerifier::Init(nsIPackagedAppVerifierListener* aListener,
- const nsACString& aPackageOrigin,
- const nsACString& aSignature,
- nsICacheEntry* aPackageCacheEntry)
-{
- static bool onceThru = false;
- if (!onceThru) {
- Preferences::AddBoolVarCache(&gSignedAppEnabled,
- "network.http.signed-packages.enabled", false);
- onceThru = true;
- }
-
- mListener = aListener;
- mState = STATE_UNKNOWN;
- mSignature = aSignature;
- mIsPackageSigned = false;
- mPackageCacheEntry = aPackageCacheEntry;
- mIsFirstResource = true;
- mManifest = EmptyCString();
-
- bool success = NeckoOriginAttributes().PopulateFromOrigin(aPackageOrigin, mPackageOrigin);
- NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
- mBypassVerification = (mPackageOrigin ==
- Preferences::GetCString("network.http.signed-packages.trusted-origin"));
-
- LOG(("mBypassVerification = %d\n", mBypassVerification));
- LOG(("mPackageOrigin = %s\n", mPackageOrigin.get()));
-
- nsresult rv;
- mPackagedAppUtils = do_CreateInstance(NS_PACKAGEDAPPUTILS_CONTRACTID, &rv);
- if (NS_FAILED(rv)) {
- LOG(("create packaged app utils failed"));
- return rv;
- }
-
- return NS_OK;
-}
-
-//----------------------------------------------------------------------
-// nsIStreamListener
-//----------------------------------------------------------------------
-
-// @param aRequest nullptr.
-// @param aContext The URI of the resource. (nsIURI)
-NS_IMETHODIMP
-PackagedAppVerifier::OnStartRequest(nsIRequest *aRequest,
- nsISupports *aContext)
-{
- if (mIsFirstResource) {
- // The first resource must be the manifest, hashes not needed
- return NS_OK;
- }
-
- if (!mHasher) {
- mHasher = do_CreateInstance("@mozilla.org/security/hash;1");
- }
-
- NS_ENSURE_TRUE(mHasher, NS_ERROR_FAILURE);
-
- nsCOMPtr<nsIURI> uri = do_QueryInterface(aContext);
- NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
- uri->GetAsciiSpec(mHashingResourceURI);
-
- return mHasher->Init(kResourceHashType);
-}
-
-nsresult
-PackagedAppVerifier::WriteManifest(nsIInputStream* aStream,
- void* aManifest,
- const char* aFromRawSegment,
- uint32_t aToOffset,
- uint32_t aCount,
- uint32_t* aWriteCount)
-{
- LOG(("WriteManifest: length %u", aCount));
- LOG(("%s", nsCString(aFromRawSegment, aCount).get()));
- nsCString* manifest = static_cast<nsCString*>(aManifest);
- manifest->AppendASCII(aFromRawSegment, aCount);
- *aWriteCount = aCount;
- return NS_OK;
-}
-
-// @param aRequest nullptr.
-// @param aContext nullptr.
-// @param aInputStream as-is.
-// @param aOffset as-is.
-// @param aCount as-is.
-NS_IMETHODIMP
-PackagedAppVerifier::OnDataAvailable(nsIRequest *aRequest,
- nsISupports *aContext,
- nsIInputStream *aInputStream,
- uint64_t aOffset,
- uint32_t aCount)
-{
- if (mIsFirstResource) {
- // The first resource must be the manifest, hash value not needed.
- // Instead, we read from the input stream and append to mManifest.
- uint32_t count;
- LOG(("ReadSegments: size = %u", aCount));
- nsresult rv = aInputStream->ReadSegments(WriteManifest, &mManifest, aCount, &count);
- MOZ_ASSERT(count == aCount, "Bytes read by ReadSegments don't match");
- return rv;
- }
-
- MOZ_ASSERT(!mHashingResourceURI.IsEmpty(), "MUST call BeginResourceHash first.");
- NS_ENSURE_TRUE(mHasher, NS_ERROR_FAILURE);
- return mHasher->UpdateFromStream(aInputStream, aCount);
-}
-
-// @param aRequest nullptr.
-// @param aContext The resource cache info.
-// @param aStatusCode as-is,
-NS_IMETHODIMP
-PackagedAppVerifier::OnStopRequest(nsIRequest* aRequest,
- nsISupports* aContext,
- nsresult aStatusCode)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "mHashingResourceURI is not thread safe.");
-
- if (mIsFirstResource) {
- // The first resource must be the manifest, hash value not needed
- mIsFirstResource = false;
- } else {
- NS_ENSURE_TRUE(mHasher, NS_ERROR_FAILURE);
-
- nsAutoCString hash;
- nsresult rv = mHasher->Finish(true, hash);
- NS_ENSURE_SUCCESS(rv, rv);
-
- LOG(("Hash of %s is %s", mHashingResourceURI.get(), hash.get()));
-
- // Store the computated hash associated with the resource URI.
- mResourceHashStore.Put(mHashingResourceURI, new nsCString(hash));
- mHashingResourceURI = EmptyCString();
- }
-
- // Get a internal copy and take over the life cycle handling
- // since the linked list we use only supports pointer-based element.
- ResourceCacheInfo* info
- = new ResourceCacheInfo(*(static_cast<ResourceCacheInfo*>(aContext)));
-
- ProcessResourceCache(info);
-
- return NS_OK;
-}
-
-void
-PackagedAppVerifier::ProcessResourceCache(const ResourceCacheInfo* aInfo)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "ProcessResourceCache must be on main thread");
-
- // Queue this info since we might process it asynchronously.
- mPendingResourceCacheInfoList.insertBack(const_cast<ResourceCacheInfo*>(aInfo));
-
- switch (mState) {
- case STATE_UNKNOWN:
- // The first resource has to be the manifest.
- VerifyManifest(aInfo);
- break;
-
- case STATE_MANIFEST_VERIFYING:
- // A resource is cached in the middle of manifest verification.
- // Verify it until the manifest is verified.
- break;
-
- case STATE_MANIFEST_VERIFIED_OK:
- VerifyResource(aInfo);
- break;
-
- case STATE_MANIFEST_VERIFIED_FAILED:
- LOG(("Resource not verified because manifest verification failed."));
- FireVerifiedEvent(false, false);
- break;
-
- default:
- MOZ_CRASH("Unexpected PackagedAppVerifier state."); // Shouldn't get here.
- break;
- }
-}
-
-NS_IMETHODIMP
-PackagedAppVerifier::FireVerifiedEvent(bool aForManifest, bool aSuccess)
-{
- LOG(("FireVerifiedEvent aForManifest=%d aSuccess=%d", aForManifest, aSuccess));
- nsCOMPtr<nsIRunnable> r;
-
- if (aForManifest) {
- r = NewRunnableMethod<bool>(this,
- &PackagedAppVerifier::OnManifestVerified,
- aSuccess);
- } else {
- r = NewRunnableMethod<bool>(this,
- &PackagedAppVerifier::OnResourceVerified,
- aSuccess);
- }
-
- NS_DispatchToMainThread(r);
-
- return NS_OK;
-}
-
-void
-PackagedAppVerifier::VerifyManifest(const ResourceCacheInfo* aInfo)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Manifest verification must be on main thread");
-
- LOG(("Ready to verify manifest."));
-
- if (!aInfo->mURI) { // Broken last part.
- FireVerifiedEvent(false, false);
- mState = STATE_MANIFEST_VERIFIED_FAILED;
- return;
- }
-
- mState = STATE_MANIFEST_VERIFYING;
-
- if (mSignature.IsEmpty()) {
- LOG(("No signature. No need to do verification."));
- FireVerifiedEvent(true, true);
- return;
- }
-
- LOG(("Signature: length = %u\n%s", mSignature.Length(), mSignature.get()));
- LOG(("Manifest: length = %u\n%s", mManifest.Length(), mManifest.get()));
-
- bool useDeveloperRoot =
- !Preferences::GetCString("network.http.signed-packages.developer-root").IsEmpty();
- nsresult rv = mPackagedAppUtils->VerifyManifest(mSignature, mManifest,
- this, useDeveloperRoot);
- if (NS_FAILED(rv)) {
- LOG(("VerifyManifest FAILED rv = %u", (unsigned)rv));
- }
-}
-
-void
-PackagedAppVerifier::VerifyResource(const ResourceCacheInfo* aInfo)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Resource verification must be on main thread");
-
- if (!aInfo->mURI) { // Broken last part.
- FireVerifiedEvent(false, false);
- return;
- }
-
- // Look up the resource hash that we computed and stored to
- // mResourceHashStore before.
- nsAutoCString uriAsAscii;
- aInfo->mURI->GetAsciiSpec(uriAsAscii);
- nsCString* resourceHash = mResourceHashStore.Get(uriAsAscii);
-
- if (!resourceHash) {
- LOG(("Hash value for %s is not computed. ERROR!", uriAsAscii.get()));
- MOZ_CRASH();
- }
-
- if (mBypassVerification) {
- LOG(("Origin is trusted. Bypass integrity check."));
- FireVerifiedEvent(false, true);
- return;
- }
-
- if (mSignature.IsEmpty()) {
- LOG(("No signature. No need to do resource integrity check."));
- FireVerifiedEvent(false, true);
- return;
- }
-
- nsAutoCString path;
- nsCOMPtr<nsIURL> url(do_QueryInterface(aInfo->mURI));
- if (url) {
- url->GetFilePath(path);
- }
- int32_t pos = path.Find("!//");
- if (pos == kNotFound) {
- FireVerifiedEvent(false, false);
- return;
- }
- // Only keep the part after "!//"
- path.Cut(0, pos + 3);
-
- mPackagedAppUtils->CheckIntegrity(path, *resourceHash, this);
-}
-
-void
-PackagedAppVerifier::OnManifestVerified(bool aSuccess)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "OnManifestVerified must be on main thread.");
-
- LOG(("PackagedAppVerifier::OnManifestVerified: %d", aSuccess));
-
- // The listener could have been removed before we verify the resource.
- if (!mListener) {
- return;
- }
-
-
- if (!aSuccess && mBypassVerification) {
- aSuccess = true;
- LOG(("Developer mode! Treat junk signature valid."));
- }
-
- if (aSuccess && !mSignature.IsEmpty()) {
- // Get the package location from the manifest
- nsAutoCString packageOrigin;
- mPackagedAppUtils->GetPackageOrigin(packageOrigin);
- if (packageOrigin != mPackageOrigin) {
- aSuccess = false;
- LOG(("moz-package-location doesn't match:\nFrom: %s\nManifest: %s\n", mPackageOrigin.get(), packageOrigin.get()));
- }
- }
-
- // Only when the manifest verified and package has signature would we
- // regard this package is signed.
- mIsPackageSigned = aSuccess && !mSignature.IsEmpty();
-
- mState = aSuccess ? STATE_MANIFEST_VERIFIED_OK
- : STATE_MANIFEST_VERIFIED_FAILED;
-
- // Obtain the package identifier from manifest if the package is signed.
- if (mIsPackageSigned) {
- mPackagedAppUtils->GetPackageIdentifier(mPackageIdentifer);
- LOG(("PackageIdentifer is: %s", mPackageIdentifer.get()));
- }
-
- // If the signature verification failed, doom the package cache to
- // make its subresources unavailable in the subsequent requests.
- if (!aSuccess && mPackageCacheEntry) {
- mPackageCacheEntry->AsyncDoom(nullptr);
- }
-
- // If the package is signed, add related info to the package cache.
- if (mIsPackageSigned && mPackageCacheEntry) {
- LOG(("This package is signed. Add this info to the cache channel."));
- if (mPackageCacheEntry) {
- mPackageCacheEntry->SetMetaDataElement(kSignedPakIdMetadataKey,
- mPackageIdentifer.get());
- mPackageCacheEntry = nullptr; // the cache entry is no longer needed.
- }
- }
-
- RefPtr<ResourceCacheInfo> info(mPendingResourceCacheInfoList.popFirst());
- MOZ_ASSERT(info);
-
- mListener->OnVerified(true, // aIsManifest.
- info->mURI,
- info->mCacheEntry,
- info->mStatusCode,
- info->mIsLastPart,
- aSuccess);
-
- LOG(("Ready to verify resources that were cached during verification"));
- // Verify the resources which were cached during verification accordingly.
- for (auto i = mPendingResourceCacheInfoList.getFirst(); i; i = i->getNext()) {
- VerifyResource(i);
- }
-}
-
-void
-PackagedAppVerifier::OnResourceVerified(bool aSuccess)
-{
- MOZ_RELEASE_ASSERT(NS_IsMainThread(),
- "PackagedAppVerifier::OnResourceVerified must be on main thread");
-
- // The listener could have been removed before we verify the resource.
- if (!mListener) {
- return;
- }
-
- RefPtr<ResourceCacheInfo> info(mPendingResourceCacheInfoList.popFirst());
- MOZ_ASSERT(info);
-
- mListener->OnVerified(false, // aIsManifest.
- info->mURI,
- info->mCacheEntry,
- info->mStatusCode,
- info->mIsLastPart,
- aSuccess);
-}
-
-void
-PackagedAppVerifier::SetHasBrokenLastPart(nsresult aStatusCode)
-{
- // Append a record with null URI as a broken last part.
-
- ResourceCacheInfo* info
- = new ResourceCacheInfo(nullptr, nullptr, aStatusCode, true);
-
- mPendingResourceCacheInfoList.insertBack(info);
-}
-
-bool
-PackagedAppVerifier::WouldVerify() const
-{
- return gSignedAppEnabled && !mSignature.IsEmpty();
-}
-
-//---------------------------------------------------------------
-// nsIPackagedAppVerifier.
-//---------------------------------------------------------------
-
-NS_IMETHODIMP
-PackagedAppVerifier::GetPackageIdentifier(nsACString& aPackageIdentifier)
-{
- aPackageIdentifier = mPackageIdentifer;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-PackagedAppVerifier::GetIsPackageSigned(bool* aIsPackagedSigned)
-{
- *aIsPackagedSigned = mIsPackageSigned;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-PackagedAppVerifier::CreateResourceCacheInfo(nsIURI* aUri,
- nsICacheEntry* aCacheEntry,
- nsresult aStatusCode,
- bool aIsLastPart,
- nsISupports** aReturn)
-{
- nsCOMPtr<nsISupports> info =
- new ResourceCacheInfo(aUri, aCacheEntry, aStatusCode, aIsLastPart);
-
- info.forget(aReturn);
-
- return NS_OK;
-}
-
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/http/PackagedAppVerifier.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et 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_net_PackagedAppVerifier_h
-#define mozilla_net_PackagedAppVerifier_h
-
-#include "nsICacheEntry.h"
-#include "nsIURI.h"
-#include "nsClassHashtable.h"
-#include "nsHashKeys.h"
-#include "nsICryptoHash.h"
-#include "nsIPackagedAppVerifier.h"
-#include "mozilla/LinkedList.h"
-#include "nsIPackagedAppUtils.h"
-
-namespace mozilla {
-namespace net {
-
-class PackagedAppVerifier final
- : public nsIPackagedAppVerifier
- , public nsIVerificationCallback
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIREQUESTOBSERVER
- NS_DECL_NSISTREAMLISTENER
- NS_DECL_NSIPACKAGEDAPPVERIFIER
- NS_DECL_NSIVERIFICATIONCALLBACK
-
-public:
- enum EState {
- // The initial state.
- STATE_UNKNOWN,
-
- // When we are notified to process the first resource, we will start to
- // verify the manifest and go to this state no matter the package has
- // signature or not.
- STATE_MANIFEST_VERIFYING,
-
- // Either the package has no signature or the manifest is verified
- // successfully will we be in this state.
- STATE_MANIFEST_VERIFIED_OK,
-
- // iff the package has signature but the manifest is not well signed.
- STATE_MANIFEST_VERIFIED_FAILED,
-
- // The manifest is well signed but the resource integrity check failed.
- STATE_RESOURCE_VERIFIED_FAILED,
- };
-
- // The only reason to inherit from nsISupports is it needs to be
- // passed as the context to PackagedAppVerifier::OnStopRequest.
- class ResourceCacheInfo : public nsISupports
- , public mozilla::LinkedListElement<ResourceCacheInfo>
- {
- public:
- NS_DECL_ISUPPORTS
-
- ResourceCacheInfo(nsIURI* aURI,
- nsICacheEntry* aCacheEntry,
- nsresult aStatusCode,
- bool aIsLastPart)
- : mURI(aURI)
- , mCacheEntry(aCacheEntry)
- , mStatusCode(aStatusCode)
- , mIsLastPart(aIsLastPart)
- {
- }
-
- ResourceCacheInfo(const ResourceCacheInfo& aCopyFrom)
- : mURI(aCopyFrom.mURI)
- , mCacheEntry(aCopyFrom.mCacheEntry)
- , mStatusCode(aCopyFrom.mStatusCode)
- , mIsLastPart(aCopyFrom.mIsLastPart)
- {
- }
-
- // A ResourceCacheInfo must have a URI. If mURI is null, this
- // resource is broken.
- nsCOMPtr<nsIURI> mURI;
- nsCOMPtr<nsICacheEntry> mCacheEntry;
- nsresult mStatusCode;
- bool mIsLastPart;
-
- private:
- virtual ~ResourceCacheInfo() { }
- };
-
-public:
- PackagedAppVerifier();
-
- PackagedAppVerifier(nsIPackagedAppVerifierListener* aListener,
- const nsACString& aPackageOrigin,
- const nsACString& aSignature,
- nsICacheEntry* aPackageCacheEntry);
-
- // A internal used function to let the verifier know there's a broken
- // last part.
- void SetHasBrokenLastPart(nsresult aStatusCode);
-
- // Used to explicitly clear the listener to avoid circula reference.
- void ClearListener() { mListener = nullptr; }
-
- bool GetIsPackageSigned() const
- {
- return mIsPackageSigned;
- }
-
- const nsACString& GetPackageIdentifier() const
- {
- return mPackageIdentifer;
- }
-
- bool WouldVerify() const;
-
- static const char* kSignedPakIdMetadataKey;
-
-private:
- virtual ~PackagedAppVerifier();
-
- // Called when a resource is already fully written in the cache. This resource
- // will be processed and is guaranteed to be called back in either:
- //
- // 1) PackagedAppVerifierListener::OnManifestVerified:
- // ------------------------------------------------------------------------
- // If the resource is the first one in the package, it will be called
- // back in OnManifestVerified no matter this package has a signature or not.
- //
- // 2) PackagedAppVerifierListener::OnResourceVerified.
- // ------------------------------------------------------------------------
- // Otherwise, the resource will be called back here.
- //
- void ProcessResourceCache(const ResourceCacheInfo* aInfo);
-
- // Callback for nsIInputStream::ReadSegment() to read manifest
- static nsresult WriteManifest(nsIInputStream* aStream,
- void* aManifest,
- const char* aFromRawSegment,
- uint32_t aToOffset,
- uint32_t aCount,
- uint32_t* aWriteCount);
-
- // This two functions would call the actual verifier.
- void VerifyManifest(const ResourceCacheInfo* aInfo);
- void VerifyResource(const ResourceCacheInfo* aInfo);
-
- void OnManifestVerified(bool aSuccess);
- void OnResourceVerified(bool aSuccess);
-
- // To notify that either manifest or resource check is done.
- nsCOMPtr<nsIPackagedAppVerifierListener> mListener;
-
- // The internal verification state.
- EState mState;
-
- // Initialized as a normal origin. Will be updated once we verified the manifest.
- nsCString mPackageOrigin;
-
- // The signature of the package.
- nsCString mSignature;
-
- // The app manfiest of the package
- nsCString mManifest;
-
- // Whether we're processing the first resource, which is the manfiest
- bool mIsFirstResource;
-
- // Whether this package app is signed.
- bool mIsPackageSigned;
-
- // Whether we should bypass verification.
- bool mBypassVerification;
-
- // The package cache entry (e.g. http://foo.com/app.pak) used to store
- // any necessarry signed package information.
- nsCOMPtr<nsICacheEntry> mPackageCacheEntry;
-
- // The resource URI that we are computing its hash.
- nsCString mHashingResourceURI;
-
- // Used to compute resource's hash value.
- nsCOMPtr<nsICryptoHash> mHasher;
-
- // The last computed hash value for a resource. It will be set on every
- // |EndResourceHash| call.
- nsCString mLastComputedResourceHash;
-
- // This will help to verify manifests and resource integrity
- nsCOMPtr<nsIPackagedAppUtils> mPackagedAppUtils;
-
- // A list of pending resource that is downloaded but not verified yet.
- mozilla::LinkedList<ResourceCacheInfo> mPendingResourceCacheInfoList;
-
- // A place to store the computed hashes of each resource.
- nsClassHashtable<nsCStringHashKey, nsCString> mResourceHashStore;
-
- nsCString mPackageIdentifer;
-}; // class PackagedAppVerifier
-
-} // namespace net
-} // namespace mozilla
-
-#endif // mozilla_net_PackagedAppVerifier_h
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -34,18 +34,16 @@ EXPORTS += [
EXPORTS.mozilla.net += [
'AltDataOutputStreamChild.h',
'AltDataOutputStreamParent.h',
'HttpBaseChannel.h',
'HttpChannelChild.h',
'HttpChannelParent.h',
'HttpInfo.h',
'NullHttpChannel.h',
- 'PackagedAppService.h',
- 'PackagedAppVerifier.h',
'PHttpChannelParams.h',
'PSpdyPush.h',
'TimingStruct.h',
]
# ASpdySession.cpp and nsHttpAuthCache cannot be built in unified mode because
# they use plarena.h.
SOURCES += [
@@ -85,18 +83,16 @@ UNIFIED_SOURCES += [
'nsHttpHeaderArray.cpp',
'nsHttpNTLMAuth.cpp',
'nsHttpPipeline.cpp',
'nsHttpRequestHead.cpp',
'nsHttpResponseHead.cpp',
'nsHttpTransaction.cpp',
'NullHttpChannel.cpp',
'NullHttpTransaction.cpp',
- 'PackagedAppService.cpp',
- 'PackagedAppVerifier.cpp',
'TunnelUtils.cpp',
]
# These files cannot be built in unified mode because of OS X headers.
SOURCES += [
'nsHttpHandler.cpp',
]
@@ -115,13 +111,11 @@ include('/ipc/chromium/chromium-config.m
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base',
'/netwerk/base',
]
EXTRA_COMPONENTS += [
- 'PackagedAppUtils.js',
- 'PackagedAppUtils.manifest',
'WellKnownOpportunisticUtils.js',
'WellKnownOpportunisticUtils.manifest',
]
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -86,17 +86,16 @@
#include "mozilla/dom/Performance.h"
#include "mozilla/Telemetry.h"
#include "AlternateServices.h"
#include "InterceptedChannel.h"
#include "nsIHttpPushListener.h"
#include "nsIX509Cert.h"
#include "ScopedNSSTypes.h"
#include "nsNullPrincipal.h"
-#include "nsIPackagedAppService.h"
#include "nsIDeprecationWarner.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsICompressConvStats.h"
#include "nsCORSListenerProxy.h"
#include "nsISocketProvider.h"
#include "mozilla/net/Predictor.h"
#include "CacheControlParser.h"
@@ -260,17 +259,16 @@ nsHttpChannel::nsHttpChannel()
, mCacheEntryIsReadOnly(false)
, mCacheEntryIsWriteOnly(false)
, mCacheEntriesToWaitFor(0)
, mHasQueryString(0)
, mConcurrentCacheAccess(0)
, mIsPartialRequest(0)
, mHasAutoRedirectVetoNotifier(0)
, mPinCacheContent(0)
- , mIsPackagedAppResource(0)
, mIsCorsPreflightDone(0)
, mStronglyFramed(false)
, mPushedStream(nullptr)
, mLocalBlocklist(false)
, mWarningReporter(nullptr)
, mDidReval(false)
{
LOG(("Creating nsHttpChannel [this=%p]\n", this));
@@ -4161,22 +4159,16 @@ nsHttpChannel::OnCacheEntryAvailableInte
if (NS_FAILED(rv) && (mLoadFlags & LOAD_ONLY_FROM_CACHE)) {
// If we have a fallback URI (and we're not already
// falling back), process the fallback asynchronously.
if (!mFallbackChannel && !mFallbackKey.IsEmpty()) {
return AsyncCall(&nsHttpChannel::HandleAsyncFallback);
}
- if (mIsPackagedAppResource) {
- // We need to return FILE_NOT_FOUND in case an error occurs
- // or we will take the user to the <you're offline> screen.
- return NS_ERROR_FILE_NOT_FOUND;
- }
-
return NS_ERROR_DOCUMENT_NOT_CACHED;
}
if (NS_FAILED(rv)) {
return rv;
}
// We may be waiting for more callbacks...
@@ -5662,25 +5654,16 @@ nsHttpChannel::AsyncOpen(nsIStreamListen
MOZ_ASSERT(NS_IsMainThread());
if (!gHttpHandler->Active()) {
LOG((" after HTTP shutdown..."));
return NS_ERROR_NOT_AVAILABLE;
}
- if (gHttpHandler->PackagedAppsEnabled()) {
- nsAutoCString path;
- nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
- if (url) {
- url->GetFilePath(path);
- }
- mIsPackagedAppResource = path.Find(PACKAGED_APP_TOKEN) != kNotFound;
- }
-
rv = NS_CheckPortSafety(mURI);
if (NS_FAILED(rv)) {
ReleaseListeners();
return rv;
}
if (mInterceptCache != INTERCEPTED && ShouldIntercept()) {
mInterceptCache = MAYBE_INTERCEPT;
@@ -5921,42 +5904,16 @@ nsHttpChannel::BeginConnect()
}
}
// If mTimingEnabled flag is not set after OnModifyRequest() then
// clear the already recorded AsyncOpen value for consistency.
if (!mTimingEnabled)
mAsyncOpenTime = TimeStamp();
- if (mIsPackagedAppResource) {
- // If this is a packaged app resource, the content will be fetched
- // by the packaged app service into the cache, and the cache entry will
- // be passed to OnCacheEntryAvailable.
-
- nsCOMPtr<nsIPackagedAppService> pas =
- do_GetService("@mozilla.org/network/packaged-app-service;1", &rv);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- rv = pas->GetResource(this, this);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- // We need to alter the flags so the cache entry returned by the
- // packaged app service is always accepted. Revalidation is handled
- // by the service.
- mLoadFlags |= LOAD_ONLY_FROM_CACHE;
- mLoadFlags |= LOAD_FROM_CACHE;
- mLoadFlags &= ~VALIDATE_ALWAYS;
-
- return rv;
- }
-
// when proxying only use the pipeline bit if ProxyPipelining() allows it.
if (!mConnectionInfo->UsingConnect() && mConnectionInfo->UsingHttpProxy()) {
mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
if (gHttpHandler->ProxyPipelining())
mCaps |= NS_HTTP_ALLOW_PIPELINING;
}
// if this somehow fails we can go on without it
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -550,21 +550,16 @@ private:
uint32_t mConcurrentCacheAccess : 1;
// whether the request is setup be byte-range
uint32_t mIsPartialRequest : 1;
// true iff there is AutoRedirectVetoNotifier on the stack
uint32_t mHasAutoRedirectVetoNotifier : 1;
// consumers set this to true to use cache pinning, this has effect
// only when the channel is in an app context (load context has an appid)
uint32_t mPinCacheContent : 1;
- // Whether fetching the content is meant to be handled by the
- // packaged app service, which behaves like a caching layer.
- // Upon successfully fetching the package, the resource will be placed in
- // the cache, and served by calling OnCacheEntryAvailable.
- uint32_t mIsPackagedAppResource : 1;
// True if CORS preflight has been performed
uint32_t mIsCorsPreflightDone : 1;
// if the http transaction was performed (i.e. not cached) and
// the result in OnStopRequest was known to be correctly delimited
// by chunking, content-length, or h2 end-stream framing
uint32_t mStronglyFramed : 1;
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -309,22 +309,16 @@ nsHttpHandler::Init()
prefBranch->AddObserver(HTTP_PREF("tcp_keepalive.short_lived_connections"), this, true);
prefBranch->AddObserver(HTTP_PREF("tcp_keepalive.long_lived_connections"), this, true);
prefBranch->AddObserver(SAFE_HINT_HEADER_VALUE, this, true);
prefBranch->AddObserver(SECURITY_PREFIX, this, true);
prefBranch->AddObserver(NEW_TAB_REMOTE_MODE, this, true);
PrefsChanged(prefBranch, nullptr);
}
- rv = Preferences::AddBoolVarCache(&mPackagedAppsEnabled,
- "network.http.enable-packaged-apps", false);
- if (NS_FAILED(rv)) {
- mPackagedAppsEnabled = false;
- }
-
nsHttpChannelAuthProvider::InitializePrefs();
mMisc.AssignLiteral("rv:" MOZILLA_UAVERSION);
mCompatFirefox.AssignLiteral("Firefox/" MOZILLA_UAVERSION);
nsCOMPtr<nsIXULAppInfo> appInfo =
do_GetService("@mozilla.org/xre/app-info;1");
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -81,17 +81,16 @@ public:
nsHttpVersion ProxyHttpVersion() { return mProxyHttpVersion; }
uint8_t ReferrerLevel() { return mReferrerLevel; }
bool SpoofReferrerSource() { return mSpoofReferrerSource; }
uint8_t ReferrerTrimmingPolicy() { return mReferrerTrimmingPolicy; }
uint8_t ReferrerXOriginTrimmingPolicy() {
return mReferrerXOriginTrimmingPolicy;
}
uint8_t ReferrerXOriginPolicy() { return mReferrerXOriginPolicy; }
- bool PackagedAppsEnabled() { return mPackagedAppsEnabled; }
uint8_t RedirectionLimit() { return mRedirectionLimit; }
PRIntervalTime IdleTimeout() { return mIdleTimeout; }
PRIntervalTime SpdyTimeout() { return mSpdyTimeout; }
PRIntervalTime ResponseTimeout() {
return mResponseTimeoutEnabled ? mResponseTimeout : 0;
}
PRIntervalTime ResponseTimeoutEnabled() { return mResponseTimeoutEnabled; }
uint32_t NetworkChangedTimeout() { return mNetworkChangedTimeout; }
@@ -447,19 +446,16 @@ private:
uint16_t mMaxOptimisticPipelinedRequests;
bool mPipelineAggressive;
int64_t mMaxPipelineObjectSize;
bool mPipelineRescheduleOnTimeout;
PRIntervalTime mPipelineRescheduleTimeout;
PRIntervalTime mPipelineReadTimeout;
nsCOMPtr<nsITimer> mPipelineTestTimer;
- // Whether a URL containing !// should be interpreted as a packaged app channel
- bool mPackagedAppsEnabled = false;
-
uint8_t mRedirectionLimit;
// we'll warn the user if we load an URL containing a userpass field
// unless its length is less than this threshold. this warning is
// intended to protect the user against spoofing attempts that use
// the userpass field of the URL to obscure the actual origin server.
uint8_t mPhishyUserPassLength;
deleted file mode 100644
--- a/netwerk/test/unit/test_packaged_app_bug1214079.js
+++ /dev/null
@@ -1,178 +0,0 @@
-// This test is to verify Bug 1214079: when we failed to load a signed packaged
-// content due to the bad signature, we are able to load in the next time since
-// the cache is not cleaned up after signature verification.
-//
-// In order to verify it, we do two identical requests in a row, where the
-// second request will be loaded from cache. The request is made for a signed
-// package with bad signature. If the package cache isn't doomed after the
-// first load, the second request will get valid data from the cache.
-
-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 gPrefs = Cc["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
-
-var badSignature = [
- "manifest-signature: AAAAAAAAAAAAAAAAAAAAA\r",
- "--7B0MKBI3UH\r",
- "Content-Location: manifest.webapp\r",
- "Content-Type: application/x-web-app-manifest+json\r",
- "\r",
- "{",
- " \"name\": \"My App\",",
- " \"moz-resources\": [",
- " {",
- " \"src\": \"page2.html\",",
- " \"integrity\": \"JREF3JbXGvZ+I1KHtoz3f46ZkeIPrvXtG4VyFQrJ7II=\"",
- " },",
- " {",
- " \"src\": \"index.html\",",
- " \"integrity\": \"zEubR310nePwd30NThIuoCxKJdnz7Mf5z+dZHUbH1SE=\"",
- " },",
- " {",
- " \"src\": \"scripts/script.js\",",
- " \"integrity\": \"6TqtNArQKrrsXEQWu3D9ZD8xvDRIkhyV6zVdTcmsT5Q=\"",
- " },",
- " {",
- " \"src\": \"scripts/library.js\",",
- " \"integrity\": \"TN2ByXZiaBiBCvS4MeZ02UyNi44vED+KjdjLInUl4o8=\"",
- " }",
- " ],",
- " \"moz-permissions\": [",
- " {",
- " \"systemXHR\": {",
- " \"description\": \"Needed to download stuff\"",
- " },",
- " \"devicestorage:pictures\": {",
- " \"description\": \"Need to load pictures\"",
- " }",
- " }",
- " ],",
- " \"package-identifier\": \"611FC2FE-491D-4A47-B3B3-43FBDF6F404F\",",
- " \"moz-package-location\": \"https://example.com/myapp/app.pak\",",
- " \"description\": \"A great app!\"",
- "}\r",
- "--7B0MKBI3UH\r",
- "Content-Location: page2.html\r",
- "Content-Type: text/html\r",
- "\r",
- "<html>",
- " page2.html",
- "</html>",
- "\r",
- "--7B0MKBI3UH\r",
- "Content-Location: index.html\r",
- "Content-Type: text/html\r",
- "\r",
- "<html>",
- " Last updated: 2015/10/01 14:10 PST",
- "</html>",
- "\r",
- "--7B0MKBI3UH\r",
- "Content-Location: scripts/script.js\r",
- "Content-Type: text/javascript\r",
- "\r",
- "// script.js",
- "\r",
- "--7B0MKBI3UH\r",
- "Content-Location: scripts/library.js\r",
- "Content-Type: text/javascript\r",
- "\r",
- "// library.js",
- "\r",
- "--7B0MKBI3UH--"
-].join("\n");
-
-XPCOMUtils.defineLazyGetter(this, "uri", function() {
- return "http://localhost:" + httpserver.identity.primaryPort;
-});
-
-// The active http server initialized in run_test
-var httpserver = null;
-// The packaged app service initialized in run_test
-var paservice = null;
-
-function run_test()
-{
- // setup test
- httpserver = new HttpServer();
- httpserver.registerPathHandler("/badSignature", badSignatureHandler);
- httpserver.start(-1);
-
- do_register_cleanup(function() {
- gPrefs.clearUserPref("network.http.signed-packages.enabled");
- });
-
- paservice = Cc["@mozilla.org/network/packaged-app-service;1"]
- .getService(Ci.nsIPackagedAppService);
- ok(!!paservice, "test service exists");
-
- gPrefs.setBoolPref("network.http.signed-packages.enabled", true);
-
- add_test(test_badSignature_package);
- add_test(test_badSignature_package);
-
- // run tests
- run_next_test();
-}
-
-//-----------------------------------------------------------------------------
-
-// The number of times this package has been requested
-// This number might be reset by tests that use it
-var packagedAppRequestsMade = 0;
-
-function badSignatureHandler(metadata, response)
-{
- packagedAppRequestsMade++;
- if (packagedAppRequestsMade == 2) {
- // The second request returns a 304 not modified response
- response.setStatusLine(metadata.httpVersion, 304, "Not Modified");
- response.bodyOutputStream.write("", 0);
- return;
- }
-
- response.setHeader("Content-Type", 'application/package');
- var body = badSignature;
- response.bodyOutputStream.write(body, body.length);
-}
-
-function getChannelForURL(url) {
- let uri = createURI(url);
- let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
- .getService(Ci.nsIScriptSecurityManager);
- let principal = ssm.createCodebasePrincipal(uri, {});
- let tmpChannel =
- NetUtil.newChannel({
- uri: url,
- loadingPrincipal: principal,
- securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
- contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER
- });
-
- tmpChannel.loadInfo.originAttributes = principal.originAttributes;
-
- return tmpChannel;
-}
-
-function test_badSignature_package()
-{
- let packagePath = "/badSignature";
- let url = uri + packagePath + "!//index.html";
- let channel = getChannelForURL(url);
-
- paservice.getResource(channel, {
- onCacheEntryCheck: function() { return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; },
- onCacheEntryAvailable: function (entry, isnew, appcache, status) {
- // XXX: it returns NS_ERROR_FAILURE for a missing package
- // and NS_ERROR_FILE_NOT_FOUND for a missing file from the package.
- // Maybe make them both return NS_ERROR_FILE_NOT_FOUND?
- notEqual(status, Cr.NS_OK, "NOT FOUND");
- ok(!entry, "There should be no entry");
- run_next_test();
- }
- });
-}
deleted file mode 100644
--- a/netwerk/test/unit/test_packaged_app_channel.js
+++ /dev/null
@@ -1,288 +0,0 @@
-//
-// This tests checks that a regular http channel can be used to load a
-// packaged app resource. It sets the network.http.enable-packaged-apps pref
-// to enable this feature, then creates a channel and loads the resource.
-// reset_pref resets the pref at the end of the test.
-
-Cu.import("resource://testing-common/httpd.js");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-
-
-XPCOMUtils.defineLazyGetter(this, "uri", function() {
- return "http://localhost:" + httpserver.identity.primaryPort;
-});
-
-const nsIBinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1",
- "nsIBinaryInputStream",
- "setInputStream"
- );
-
-
-function make_channel(url) {
- return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
-}
-
-function Listener(callback) {
- this._callback = callback;
-}
-
-Listener.prototype = {
- gotStartRequest: false,
- available: -1,
- gotStopRequestOK: false,
- gotFileNotFound: false,
- QueryInterface: function(iid) {
- if (iid.equals(Ci.nsISupports) ||
- iid.equals(Ci.nsIRequestObserver))
- return this;
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
- onDataAvailable: function(request, ctx, stream, offset, count) {
- try {
- this.available = stream.available();
- do_check_eq(this.available, count);
- // Need to consume stream to avoid assertion
- var str = new nsIBinaryInputStream(stream).readBytes(count);
- equal(str, "<html>\n Last updated: 2015/10/01 14:10 PST\n</html>\n", "check proper content");
- }
- catch (ex) {
- do_throw(ex);
- }
- },
- onStartRequest: function(request, ctx) {
- this.gotStartRequest = true;
- },
- onStopRequest: function(request, ctx, status) {
- this.gotStopRequestOK = (Cr.NS_OK === status);
- this.gotFileNotFound = (Cr.NS_ERROR_FILE_NOT_FOUND === status);
- if (this._callback) {
- this._callback.call(null, this);
- }
- }
-};
-
-// The package content
-// getData formats it as described at http://www.w3.org/TR/web-packaging/#streamable-package-format
-var testData = {
- packageHeader: "manifest-signature: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\r\n",
- content: [
- { headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\n Last updated: 2015/10/01 14:10 PST\n</html>\n", type: "text/html" },
- { headers: ["Content-Location: /scripts/app.js", "Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
- { headers: ["Content-Location: /scripts/helpers/math.js", "Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" }
- ],
- token : "gc0pJq0M:08jU534c0p",
- getData: function() {
- var str = "";
- for (var i in this.content) {
- str += "--" + this.token + "\r\n";
- for (var j in this.content[i].headers) {
- str += this.content[i].headers[j] + "\r\n";
- }
- str += "\r\n";
- str += this.content[i].data + "\r\n";
- }
-
- str += "--" + this.token + "--";
- return str;
- }
-}
-
-var badSignature = "manifest-signature: MIIF1AYJKoZIhvcNAQcCoIIFxTCCBcECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCA54wggOaMIICgqADAgECAgECMA0GCSqGSIb3DQEBCwUAMHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEkMCIGA1UEChMbRXhhbXBsZSBUcnVzdGVkIENvcnBvcmF0aW9uMRkwFwYDVQQDExBUcnVzdGVkIFZhbGlkIENBMB4XDTE1MDkxMDA4MDQzNVoXDTM1MDkxMDA4MDQzNVowdDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGjAYBgNVBAMTEVRydXN0ZWQgQ29ycCBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAts8whjOzEbn/w1xkFJ67af7F/JPujBK91oyJekh2schIMzFau9pY8S1AiJQoJCulOJCJfUc8hBLKBZiGAkii+4Gpx6cVqMLe6C22MdD806Soxn8Dg4dQqbIvPuI4eeVKu5CEk80PW/BaFMmRvRHO62C7PILuH6yZeGHC4P7dTKpsk4CLxh/jRGXLC8jV2BCW0X+3BMbHBg53NoI9s1Gs7KGYnfOHbBP5wEFAa00RjHnubUaCdEBlC8Kl4X7p0S4RGb3rsB08wgFe9EmSZHIgcIm+SuVo7N4qqbI85qo2ulU6J8NN7ZtgMPHzrMhzgAgf/KnqPqwDIxnNmRNJmHTUYwIDAQABozgwNjAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAukH6cJUUj5faa8CuPCqrEa0PoLY4SYNnff9NI+TTAHkB9l+kOcFl5eo2EQOcWmZKYi7QLlWC4jy/KQYattO9FMaxiOQL4FAc6ZIbNyfwWBzZWyr5syYJTTTnkLq8A9pCKarN49+FqhJseycU+8EhJEJyP5pv5hLvDNTTHOQ6SXhASsiX8cjo3AY4bxA5pWeXuTZ459qDxOnQd+GrOe4dIeqflk0hA2xYKe3SfF+QlK8EO370B8Dj8RX230OATM1E3OtYyALe34KW3wM9Qm9rb0eViDnVyDiCWkhhQnw5yPg/XQfloug2itRYuCnfUoRt8xfeHgwz2Ymz8cUADn3KpTGCAf4wggH6AgEBMHgwczELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFRydXN0ZWQgVmFsaWQgQ0ECAQIwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE1MTAwMTIxMTEwNlowIwYJKoZIhvcNAQkEMRYEFHAisUYrrt+gBxYFhZ5KQQusOmN3MA0GCSqGSIb3DQEBAQUABIIBACHW4V0BsPWOvWrGOTRj6mPpNbH/JI1bN2oyqQZrpUQoaBY+BbYxO7TY4Uwe+aeIR/TTPJznOMF/dl3Bna6TPabezU4ylg7TVFI6W7zC5f5DZKp+Xv6uTX6knUzbbW1fkJqMtE8hGUzYXc3/C++Ci6kuOzrpWOhk6DpJHeUO/ioV56H0+QK/oMAjYpEsOohaPqvTPNOBhMQ0OQP3bmuJ6HcjZ/oz96PpzXUPKT1tDe6VykIYkV5NvtC8Tu2lDbYvp9ug3gyDgdyNSV47y5i/iWkzEhsAJB+9Z50wKhplnkxxVHEXkB/6tmfvExvQ28gLd/VbaEGDX2ljCaTSUjhD0o0=\r\n";
-
-function packageContent(origin) {
- return [
- "--7B0MKBI3UH\r",
- "Content-Location: manifest.webapp\r",
- "Content-Type: application/x-web-app-manifest+json\r",
- "\r",
- "{",
- " \"name\": \"My App\",",
- " \"moz-resources\": [",
- " {",
- " \"src\": \"page2.html\",",
- " \"integrity\": \"JREF3JbXGvZ+I1KHtoz3f46ZkeIPrvXtG4VyFQrJ7II=\"",
- " },",
- " {",
- " \"src\": \"index.html\",",
- " \"integrity\": \"zEubR310nePwd30NThIuoCxKJdnz7Mf5z+dZHUbH1SE=\"",
- " },",
- " {",
- " \"src\": \"scripts/script.js\",",
- " \"integrity\": \"6TqtNArQKrrsXEQWu3D9ZD8xvDRIkhyV6zVdTcmsT5Q=\"",
- " },",
- " {",
- " \"src\": \"scripts/library.js\",",
- " \"integrity\": \"TN2ByXZiaBiBCvS4MeZ02UyNi44vED+KjdjLInUl4o8=\"",
- " }",
- " ],",
- " \"moz-permissions\": [",
- " {",
- " \"systemXHR\": {",
- " \"description\": \"Needed to download stuff\"",
- " },",
- " \"devicestorage:pictures\": {",
- " \"description\": \"Need to load pictures\"",
- " }",
- " }",
- " ],",
- " \"package-identifier\": \"611FC2FE-491D-4A47-B3B3-43FBDF6F404F\",",
- " \"moz-package-origin\": \"" + origin + "\",",
- " \"description\": \"A great app!\"",
- "}\r",
- "--7B0MKBI3UH\r",
- "Content-Location: page2.html\r",
- "Content-Type: text/html\r",
- "\r",
- "<html>",
- " page2.html",
- "</html>",
- "\r",
- "--7B0MKBI3UH\r",
- "Content-Location: index.html\r",
- "Content-Type: text/html\r",
- "\r",
- "<html>",
- " Last updated: 2015/10/01 14:10 PST",
- "</html>",
- "\r",
- "--7B0MKBI3UH\r",
- "Content-Location: scripts/script.js\r",
- "Content-Type: text/javascript\r",
- "\r",
- "// script.js",
- "\r",
- "--7B0MKBI3UH\r",
- "Content-Location: scripts/library.js\r",
- "Content-Type: text/javascript\r",
- "\r",
- "// library.js",
- "\r",
- "--7B0MKBI3UH--"
-].join("\n");
-}
-
-function contentHandler(metadata, response)
-{
- response.setHeader("Content-Type", 'application/package');
- var body = testData.getData();
- response.bodyOutputStream.write(body, body.length);
-}
-
-function regularContentHandler(metadata, response)
-{
- var body = "response";
- response.bodyOutputStream.write(body, body.length);
-}
-
-function contentHandlerWithBadSignature(metadata, response)
-{
- response.setHeader("Content-Type", 'application/package');
- var body = badSignature + packageContent(uri);
- response.bodyOutputStream.write(body, body.length);
-}
-
-function contentHandlerWithGoodSignature(metadata, response)
-{
- response.setHeader("Content-Type", 'application/package');
- var body = goodSignature + packageContent(uri);
- response.bodyOutputStream.write(body, body.length);
-}
-
-var httpserver = null;
-var originalPref = false;
-var originalSignedAppEnabled = false;
-
-function run_test()
-{
- // setup test
- httpserver = new HttpServer();
- httpserver.registerPathHandler("/package", contentHandler);
- httpserver.registerPathHandler("/regular", regularContentHandler);
- httpserver.registerPathHandler("/package_with_good_signature", contentHandlerWithGoodSignature);
- httpserver.registerPathHandler("/package_with_bad_signature", contentHandlerWithBadSignature);
- httpserver.start(-1);
-
- // Enable the feature and save the original pref value
- originalPref = Services.prefs.getBoolPref("network.http.enable-packaged-apps");
- originalSignedAppEnabled = Services.prefs.getBoolPref("network.http.signed-packages.enabled");
- Services.prefs.setBoolPref("network.http.enable-packaged-apps", true);
- Services.prefs.setBoolPref("network.http.signed-packages.enabled", true);
- do_register_cleanup(reset_pref);
-
- add_test(test_channel);
- add_test(test_channel_uris);
-
- add_test(test_channel_with_bad_signature_from_trusted_origin);
- add_test(test_channel_with_bad_signature);
-
- // run tests
- run_next_test();
-}
-
-function test_channel_with_bad_signature() {
- var channel = make_channel(uri+"/package_with_bad_signature!//index.html");
- channel.loadInfo.originAttributes = new OriginAttributes(1024, false);
- channel.asyncOpen2(new Listener(function(l) {
- do_check_true(l.gotFileNotFound);
- run_next_test();
- }));
-}
-
-function test_channel_with_bad_signature_from_trusted_origin() {
- let pref = "network.http.signed-packages.trusted-origin";
- ok(!!Ci.nsISupportsString, "Ci.nsISupportsString");
- let origin = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
- origin.data = uri;
- Services.prefs.setComplexValue(pref, Ci.nsISupportsString, origin);
- var channel = make_channel(uri+"/package_with_bad_signature!//index.html");
- channel.loadInfo.originAttributes = new OriginAttributes(1024, false);
- channel.asyncOpen2(new Listener(function(l) {
- do_check_true(l.gotStopRequestOK);
- Services.prefs.clearUserPref(pref);
- run_next_test();
- }));
-}
-
-function test_channel_with_good_signature() {
- var channel = make_channel(uri+"/package_with_good_signature!//index.html");
- channel.loadInfo.originAttributes = new OriginAttributes(1024, false);
- channel.asyncOpen2(new Listener(function(l) {
- do_check_true(l.gotStopRequestOK);
- run_next_test();
- }));
-}
-
-function test_channel() {
- var channel = make_channel(uri+"/package!//index.html");
- channel.loadInfo.originAttributes = { appId: 1024,
- inIsolatedMozBrowser: false
- };
-
- channel.asyncOpen2(new Listener(function(l) {
- // XXX: no content length available for this resource
- //do_check_true(channel.contentLength > 0);
- do_check_true(l.gotStartRequest);
- do_check_true(l.gotStopRequestOK);
- run_next_test();
- }));
-}
-
-function test_channel_uris() {
- // A `!//` in the query or ref should not be handled as a packaged app resource
- var channel = make_channel(uri+"/regular?bla!//bla#bla!//bla");
- channel.asyncOpen2(new ChannelListener(check_regular_response, null));
-}
-
-function check_regular_response(request, buffer) {
- request.QueryInterface(Components.interfaces.nsIHttpChannel);
- do_check_eq(request.responseStatus, 200);
- do_check_eq(buffer, "response");
- run_next_test();
-}
-
-function reset_pref() {
- // Set the pref to its original value
- Services.prefs.setBoolPref("network.http.enable-packaged-apps", originalPref);
- Services.prefs.setBoolPref("network.http.signed-packages.enabled", originalSignedAppEnabled);
-}
deleted file mode 100644
--- a/netwerk/test/unit/test_packaged_app_service.js
+++ /dev/null
@@ -1,599 +0,0 @@
-//
-// This file tests the packaged app service - nsIPackagedAppService
-// NOTE: The order in which tests are run is important
-// If you need to add more tests, it's best to define them at the end
-// of the file and to add them at the end of run_test
-//
-// ----------------------------------------------------------------------------
-//
-// test_bad_args
-// - checks that calls to nsIPackagedAppService::GetResource do not accept a null argument
-// test_callback_gets_called
-// - checks the regular use case -> requesting a resource should asynchronously return an entry
-// test_same_content
-// - makes another request for the same file, and checks that the same content is returned
-// test_request_number
-// - this test does not make a request, but checks that the package has only
-// been requested once. The entry returned by the call to getResource in
-// test_same_content should be returned from the cache.
-//
-// test_package_does_not_exist
-// - checks that requesting a file from a <package that does not exist>
-// calls the listener with an error code
-// test_file_does_not_exist
-// - checks that requesting a <subresource that doesn't exist> inside a
-// package calls the listener with an error code
-//
-// test_bad_package
-// - tests that a package with missing headers for some of the files
-// will still return files that are correct
-// test_bad_package_404
-// - tests that a request for a missing subresource doesn't hang if
-// if the last file in the package is missing some headers
-//
-// test_worse_package
-// - tests that a request for a missing/existing resource doesn't
-// break the service and the async verifier.
-//
-
-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 gPrefs = Cc["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
-
-// The number of times this package has been requested
-// This number might be reset by tests that use it
-var packagedAppRequestsMade = 0;
-// The default content handler. It just responds by sending the package data
-// with an application/package content type
-function packagedAppContentHandler(metadata, response)
-{
- packagedAppRequestsMade++;
- if (packagedAppRequestsMade == 2) {
- // The second request returns a 304 not modified response
- response.setStatusLine(metadata.httpVersion, 304, "Not Modified");
- response.bodyOutputStream.write("", 0);
- return;
- }
- response.setHeader("Content-Type", 'application/package');
- var body = testData.getData();
-
- if (packagedAppRequestsMade == 3) {
- // The third request returns a 200 OK response with a slightly different content
- body = body.replace(/\.\.\./g, 'xxx');
- }
- response.bodyOutputStream.write(body, body.length);
-}
-
-function getChannelForURL(url, notificationCallbacks) {
- let uri = createURI(url);
- let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
- .getService(Ci.nsIScriptSecurityManager);
- let principal = ssm.createCodebasePrincipal(uri, {});
- let tmpChannel =
- NetUtil.newChannel({
- uri: url,
- loadingPrincipal: principal,
- securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
- contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER
- });
-
- if (notificationCallbacks) {
- tmpChannel.loadInfo.originAttributes = { appId: 1024,
- inIsolatedMozBrowser: false
- };
- // Use custom notificationCallbacks if any.
- tmpChannel.notificationCallbacks = notificationCallbacks;
- } else {
- tmpChannel.loadInfo.originAttributes = { appId: principal.appId,
- inIsolatedMozBrowser: principal.isInIsolatedMozBrowserElement
- };
- // After bug 1291652, we should get originAttributes from the nsILoadInfo,
- // bug not from the nsILoadContext.
- tmpChannel.notificationCallbacks = null;
- }
-
- return tmpChannel;
-}
-
-// The package content
-// getData formats it as described at http://www.w3.org/TR/web-packaging/#streamable-package-format
-var testData = {
- packageHeader: 'manifest-signature: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\r\n',
- content: [
- { headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- { headers: ["Content-Location: /scripts/app.js", "Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
- { headers: ["Content-Location: /scripts/helpers/math.js", "Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" }
- ],
- token : "gc0pJq0M:08jU534c0p",
- getData: function() {
- var str = "";
- for (var i in this.content) {
- str += "--" + this.token + "\r\n";
- for (var j in this.content[i].headers) {
- str += this.content[i].headers[j] + "\r\n";
- }
- str += "\r\n";
- str += this.content[i].data + "\r\n";
- }
-
- str += "--" + this.token + "--";
- return str;
- }
-}
-
-function signedPackage(origin) {
- return [
- "manifest-signature: MIIF1AYJKoZIhvcNAQcCoIIFxTCCBcECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCA54wggOaMIICgqADAgECAgECMA0GCSqGSIb3DQEBCwUAMHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEkMCIGA1UEChMbRXhhbXBsZSBUcnVzdGVkIENvcnBvcmF0aW9uMRkwFwYDVQQDExBUcnVzdGVkIFZhbGlkIENBMB4XDTE1MDkxMDA4MDQzNVoXDTM1MDkxMDA4MDQzNVowdDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGjAYBgNVBAMTEVRydXN0ZWQgQ29ycCBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAts8whjOzEbn/w1xkFJ67af7F/JPujBK91oyJekh2schIMzFau9pY8S1AiJQoJCulOJCJfUc8hBLKBZiGAkii+4Gpx6cVqMLe6C22MdD806Soxn8Dg4dQqbIvPuI4eeVKu5CEk80PW/BaFMmRvRHO62C7PILuH6yZeGHC4P7dTKpsk4CLxh/jRGXLC8jV2BCW0X+3BMbHBg53NoI9s1Gs7KGYnfOHbBP5wEFAa00RjHnubUaCdEBlC8Kl4X7p0S4RGb3rsB08wgFe9EmSZHIgcIm+SuVo7N4qqbI85qo2ulU6J8NN7ZtgMPHzrMhzgAgf/KnqPqwDIxnNmRNJmHTUYwIDAQABozgwNjAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAukH6cJUUj5faa8CuPCqrEa0PoLY4SYNnff9NI+TTAHkB9l+kOcFl5eo2EQOcWmZKYi7QLlWC4jy/KQYattO9FMaxiOQL4FAc6ZIbNyfwWBzZWyr5syYJTTTnkLq8A9pCKarN49+FqhJseycU+8EhJEJyP5pv5hLvDNTTHOQ6SXhASsiX8cjo3AY4bxA5pWeXuTZ459qDxOnQd+GrOe4dIeqflk0hA2xYKe3SfF+QlK8EO370B8Dj8RX230OATM1E3OtYyALe34KW3wM9Qm9rb0eViDnVyDiCWkhhQnw5yPg/XQfloug2itRYuCnfUoRt8xfeHgwz2Ymz8cUADn3KpTGCAf4wggH6AgEBMHgwczELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFRydXN0ZWQgVmFsaWQgQ0ECAQIwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE1MTAwMTIxMTEwNlowIwYJKoZIhvcNAQkEMRYEFHAisUYrrt+gBxYFhZ5KQQusOmN3MA0GCSqGSIb3DQEBAQUABIIBACHW4V0BsPWOvWrGOTRj6mPpNbH/JI1bN2oyqQZrpUQoaBY+BbYxO7TY4Uwe+aeIR/TTPJznOMF/dl3Bna6TPabezU4ylg7TVFI6W7zC5f5DZKp+Xv6uTX6knUzbbW1fkJqMtE8hGUzYXc3/C++Ci6kuOzrpWOhk6DpJHeUO/ioV56H0+QK/oMAjYpEsOohaPqvTPNOBhMQ0OQP3bmuJ6HcjZ/oz96PpzXUPKT1tDe6VykIYkV5NvtC8Tu2lDbYvp9ug3gyDgdyNSV47y5i/iWkzEhsAJB+9Z50wKhplnkxxVHEXkB/6tmfvExvQ28gLd/VbaEGDX2ljCaTSUjhD0o0=\r",
- "--7B0MKBI3UH\r",
- "Content-Location: manifest.webapp\r",
- "Content-Type: application/x-web-app-manifest+json\r",
- "\r",
- "{",
- " \"name\": \"My App\",",
- " \"moz-resources\": [",
- " {",
- " \"src\": \"page2.html\",",
- " \"integrity\": \"JREF3JbXGvZ+I1KHtoz3f46ZkeIPrvXtG4VyFQrJ7II=\"",
- " },",
- " {",
- " \"src\": \"index.html\",",
- " \"integrity\": \"zEubR310nePwd30NThIuoCxKJdnz7Mf5z+dZHUbH1SE=\"",
- " },",
- " {",
- " \"src\": \"scripts/script.js\",",
- " \"integrity\": \"6TqtNArQKrrsXEQWu3D9ZD8xvDRIkhyV6zVdTcmsT5Q=\"",
- " },",
- " {",
- " \"src\": \"scripts/library.js\",",
- " \"integrity\": \"TN2ByXZiaBiBCvS4MeZ02UyNi44vED+KjdjLInUl4o8=\"",
- " }",
- " ],",
- " \"moz-permissions\": [",
- " {",
- " \"systemXHR\": {",
- " \"description\": \"Needed to download stuff\"",
- " },",
- " \"devicestorage:pictures\": {",
- " \"description\": \"Need to load pictures\"",
- " }",
- " }",
- " ],",
- " \"package-identifier\": \"611FC2FE-491D-4A47-B3B3-43FBDF6F404F\",",
- " \"moz-package-origin\": \"" + origin + "\",",
- " \"description\": \"A great app!\"",
- "}\r",
- "--7B0MKBI3UH\r",
- "Content-Location: page2.html\r",
- "Content-Type: text/html\r",
- "\r",
- "<html>",
- " page2.html",
- "</html>",
- "\r",
- "--7B0MKBI3UH\r",
- "Content-Location: index.html\r",
- "Content-Type: text/html\r",
- "\r",
- "<html>",
- " Last updated: 2015/10/01 14:10 PST",
- "</html>",
- "\r",
- "--7B0MKBI3UH\r",
- "Content-Location: scripts/script.js\r",
- "Content-Type: text/javascript\r",
- "\r",
- "// script.js",
- "\r",
- "--7B0MKBI3UH\r",
- "Content-Location: scripts/library.js\r",
- "Content-Type: text/javascript\r",
- "\r",
- "// library.js",
- "\r",
- "--7B0MKBI3UH--"
-].join("\n");
-};
-
-XPCOMUtils.defineLazyGetter(this, "uri", function() {
- return "http://localhost:" + httpserver.identity.primaryPort;
-});
-
-// The active http server initialized in run_test
-var httpserver = null;
-// The packaged app service initialized in run_test
-var paservice = null;
-// This variable is set before getResource is called. The listener uses this variable
-// to check the correct resource path for the returned entry
-var packagePath = null;
-
-function run_test()
-{
- // setup test
- httpserver = new HttpServer();
- httpserver.registerPathHandler("/package", packagedAppContentHandler);
- httpserver.registerPathHandler("/304Package", packagedAppContentHandler);
- httpserver.registerPathHandler("/badPackage", packagedAppBadContentHandler);
-
- let worsePackageNum = 6;
- for (let i = 0; i < worsePackageNum; i++) {
- httpserver.registerPathHandler("/worsePackage_" + i,
- packagedAppWorseContentHandler.bind(null, i));
- }
-
- httpserver.start(-1);
-
- paservice = Cc["@mozilla.org/network/packaged-app-service;1"]
- .getService(Ci.nsIPackagedAppService);
- ok(!!paservice, "test service exists");
-
- add_test(test_bad_args);
-
- add_test(test_callback_gets_called);
- add_test(test_same_content);
- add_test(test_request_number);
- add_test(test_updated_package);
-
- add_test(test_package_does_not_exist);
- add_test(test_file_does_not_exist);
-
- add_test(test_bad_package);
- add_test(test_bad_package_404);
-
- // Channels created by addons could have no load info.
- // In debug mode this triggers an assertion, but we still want to test that
- // it works in optimized mode. See bug 1196021 comment 17
- if (Components.classes["@mozilla.org/xpcom/debug;1"]
- .getService(Components.interfaces.nsIDebug2)
- .isDebugBuild == false) {
- add_test(test_channel_no_loadinfo);
- }
-
- add_test(test_worse_package_0);
- add_test(test_worse_package_1);
- add_test(test_worse_package_2);
- add_test(test_worse_package_3);
- add_test(test_worse_package_4);
- add_test(test_worse_package_5);
-
- add_test(test_request_has_ref);
-
- // run tests
- run_next_test();
-}
-
-// This checks the proper metadata is on the entry
-var metadataListener = {
- onMetaDataElement: function(key, value) {
- if (key == 'response-head') {
- var kExpectedResponseHead = "HTTP/1.1 200 \r\nContent-Location: /index.html\r\nContent-Type: text/html\r\n";
- ok(0 === value.indexOf(kExpectedResponseHead), 'The cached response header not matched');
- }
- else if (key == 'request-method')
- equal(value, "GET");
- else
- ok(false, "unexpected metadata key")
- }
-}
-
-// A listener we use to check the proper cache entry is returned by the service
-function packagedResourceListener(content) {
- this.content = content;
-}
-
-packagedResourceListener.prototype = {
- QueryInterface: function (iid) {
- if (iid.equals(Ci.nsICacheEntryOpenCallback) ||
- iid.equals(Ci.nsISupports))
- return this;
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
- onCacheEntryCheck: function() { return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; },
- onCacheEntryAvailable: function (entry, isnew, appcache, status) {
- equal(status, Cr.NS_OK, "status is NS_OK");
- ok(!!entry, "Needs to have an entry");
- equal(entry.key, uri + packagePath + "!//index.html", "Check entry has correct name");
- entry.visitMetaData(metadataListener);
- var inputStream = entry.openInputStream(0);
- pumpReadStream(inputStream, (read) => {
- inputStream.close();
- equal(read, this.content); // not using do_check_eq since logger will fail for the 1/4MB string
- run_next_test();
- });
- }
-};
-
-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(getChannelForURL("http://test.com"), cacheListener); }, "url's with no !// aren't allowed");
- Assert.throws(() => { paservice.getResource(getChannelForURL("http://test.com/package!//test"), null); }, "should have a callback");
- Assert.throws(() => { paservice.getResource(null, cacheListener); }, "should have a channel");
-
- run_next_test();
-}
-
-// ----------------------------------------------------------------------------
-
-// This tests that the callback gets called, and the cacheListener gets the proper content.
-function test_callback_gets_called() {
- packagePath = "/package";
- let url = uri + packagePath + "!//index.html";
- paservice.getResource(getChannelForURL(url), cacheListener);
-}
-
-// Tests that requesting the same resource returns the same content
-function test_same_content() {
- packagePath = "/package";
- let url = uri + packagePath + "!//index.html";
- paservice.getResource(getChannelForURL(url), cacheListener);
-}
-
-// Check the content handler has been called the expected number of times.
-function test_request_number() {
- equal(packagedAppRequestsMade, 2, "2 requests are expected. First with content, second is a 304 not modified.");
- run_next_test();
-}
-
-// This tests that new content is returned if the package has been updated
-function test_updated_package() {
- packagePath = "/package";
- let url = uri + packagePath + "!//index.html";
- paservice.getResource(getChannelForURL(url),
- new packagedResourceListener(testData.content[0].data.replace(/\.\.\./g, 'xxx')));
-}
-
-// This tests that requested URI with reference should still work.
-function test_request_has_ref() {
- packagePath = "/package";
- let url = uri + packagePath + "!//index.html#Ref";
- paservice.getResource(getChannelForURL(url), cacheListener);
-}
-
-// ----------------------------------------------------------------------------
-
-// This listener checks that the requested resources are not returned
-// either because the package does not exist, or because the requested resource
-// is not contained in the package.
-var listener404 = {
- onCacheEntryCheck: function() { return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; },
- onCacheEntryAvailable: function (entry, isnew, appcache, status) {
- // XXX: it returns NS_ERROR_FAILURE for a missing package
- // and NS_ERROR_FILE_NOT_FOUND for a missing file from the package.
- // Maybe make them both return NS_ERROR_FILE_NOT_FOUND?
- notEqual(status, Cr.NS_OK, "NOT FOUND");
- ok(!entry, "There should be no entry");
- run_next_test();
- }
-};
-
-// Tests that an error is returned for a non existing package
-function test_package_does_not_exist() {
- packagePath = "/package_non_existent";
- let url = uri + packagePath + "!//index.html";
- paservice.getResource(getChannelForURL(url), 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
- let url = uri + packagePath + "!//file_non_existent.html";
- paservice.getResource(getChannelForURL(url), listener404);
-}
-
-// ----------------------------------------------------------------------------
-
-// Broken package. The first and last resources do not contain a "Content-Location" header
-// and should be ignored.
-var badTestData = {
- content: [
- { headers: ["Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
- { headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- { headers: ["Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" }
- ],
- token : "gc0pJq0M:08jU534c0p",
- getData: function() {
- var str = "";
- for (var i in this.content) {
- str += "--" + this.token + "\r\n";
- for (var j in this.content[i].headers) {
- str += this.content[i].headers[j] + "\r\n";
- }
- str += "\r\n";
- str += this.content[i].data + "\r\n";
- }
-
- str += "--" + this.token + "--";
- return str;
- }
-}
-
-// Returns the content of the package with "Content-Location" headers missing for the first and last resource
-function packagedAppBadContentHandler(metadata, response)
-{
- response.setHeader("Content-Type", 'application/package');
- var body = badTestData.getData();
- response.bodyOutputStream.write(body, body.length);
-}
-
-// Checks that the resource with the proper headers inside the bad package is still returned
-function test_bad_package() {
- packagePath = "/badPackage";
- let url = uri + packagePath + "!//index.html";
- paservice.getResource(getChannelForURL(url), cacheListener);
-}
-
-// Checks that the request for a non-existent resource doesn't hang for a bad package
-function test_bad_package_404() {
- packagePath = "/badPackage";
- let url = uri + packagePath + "!//file_non_existent.html";
- paservice.getResource(getChannelForURL(url), listener404);
-}
-
-// ----------------------------------------------------------------------------
-
-// NOTE: This test only runs in NON-DEBUG mode.
-function test_channel_no_loadinfo() {
- packagePath = "/package";
- let url = uri + packagePath + "!//index.html";
- let channel = getChannelForURL(url);
- channel.loadInfo = null;
- paservice.getResource(channel, cacheListener);
-}
-
-// ----------------------------------------------------------------------------
-
-// Worse package testing to ensure the async PackagedAppVerifier working good.
-
-function getData(aTestingData) {
- var str = "";
- for (var i in aTestingData.content) {
- str += "--" + aTestingData.token + "\r\n";
- for (var j in aTestingData.content[i].headers) {
- str += aTestingData.content[i].headers[j] + "\r\n";
- }
- str += "\r\n";
- str += aTestingData.content[i].data + "\r\n";
- }
-
- str += "--" + aTestingData.token + "--";
- return str;
-}
-
-var worseTestData = [
- // 0. Only one broken resource.
- { content: [
- { headers: ["Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
- ],
- token : "gc0pJq0M:08jU534c0p",
- },
-
- // 1. Only one valid resource.
- { content: [
- { headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- ],
- token : "gc0pJq0M:08jU534c0p",
- },
-
- // 2. All broken resources.
- { content: [
- { headers: ["Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
- { headers: ["Content-Type: text/javascript"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- { headers: ["Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" }
- ],
- token : "gc0pJq0M:08jU534c0p",
- },
-
- // 3. All broken resources except the first one.
- { content: [
- { headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- { headers: ["Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
- { headers: ["Content-Type: text/javascript"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- { headers: ["Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" }
- ],
- token : "gc0pJq0M:08jU534c0p",
- },
-
- // 4. All broken resources except the last one.
- { content: [
- { headers: ["Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
- { headers: ["Content-Type: text/javascript"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- { headers: ["Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" },
- { headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- ],
- token : "gc0pJq0M:08jU534c0p",
- },
-
- // 5. All broken resources except the first and the last one.
- { content: [
- { headers: ["Content-Location: /whatever.html", "Content-Type: text/html"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- { headers: ["Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
- { headers: ["Content-Type: text/javascript"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- { headers: ["Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" },
- { headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
- ],
- token : "gc0pJq0M:08jU534c0p",
- },
-];
-
-function packagedAppWorseContentHandler(index, metadata, response)
-{
- response.setHeader("Content-Type", 'application/package');
- var body = getData(worseTestData[index]);
- response.bodyOutputStream.write(body, body.length);
-}
-
-function test_worse_package(index, success) {
- packagePath = "/worsePackage_" + index;
- let url = uri + packagePath + "!//index.html";
- let channel = getChannelForURL(url);
- paservice.getResource(channel, {
- QueryInterface: function (iid) {
- if (iid.equals(Ci.nsICacheEntryOpenCallback) ||
- iid.equals(Ci.nsISupports))
- return this;
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
- onCacheEntryCheck: function() { return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; },
- onCacheEntryAvailable: function (entry, isnew, appcache, status) {
- let cacheSuccess = (status === Cr.NS_OK);
- equal(success, status === Cr.NS_OK, "Check status");
- run_next_test();
- }
- });
-}
-
-function test_worse_package_0() {
- test_worse_package(0, false);
-}
-
-function test_worse_package_1() {
- test_worse_package(1, true);
-}
-
-function test_worse_package_2() {
- test_worse_package(2, false);
-}
-
-function test_worse_package_3() {
- test_worse_package(3, true);
-}
-
-function test_worse_package_4() {
- test_worse_package(4, true);
-}
-
-function test_worse_package_5() {
- test_worse_package(5, true);
-}
-
-//-----------------------------------------------------------------------------
-
-// Used as a stub when the cache listener is not important.
-var dummyCacheListener = {
- QueryInterface: function (iid) {
- if (iid.equals(Ci.nsICacheEntryOpenCallback) ||
- iid.equals(Ci.nsISupports))
- return this;
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
- onCacheEntryCheck: function() { return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; },
- onCacheEntryAvailable: function () {}
-};
-
-function setTrustedOrigin() {
- let pref = "network.http.signed-packages.trusted-origin";
- ok(!!Ci.nsISupportsString, "Ci.nsISupportsString");
- let origin = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
- origin.data = uri;
- gPrefs.setComplexValue(pref, Ci.nsISupportsString, origin);
-}
-
-function resetTrustedOrigin() {
- gPrefs.clearUserPref("network.http.signed-packages.trusted-origin");
-}
deleted file mode 100644
--- a/netwerk/test/unit/test_packaged_app_service_paths.js
+++ /dev/null
@@ -1,137 +0,0 @@
-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)
-{
- response.setHeader("Content-Type", 'application/package');
- var body = testData.getData();
- response.bodyOutputStream.write(body, body.length);
- gRequestNo++;
-}
-
-function getChannelForURL(url) {
- let uri = createURI(url);
- let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
- .getService(Ci.nsIScriptSecurityManager);
- let principal = ssm.createCodebasePrincipal(uri, {});
- let tmpChannel =
- NetUtil.newChannel({
- uri: url,
- loadingPrincipal: principal,
- securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
- contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER
- });
-
- return tmpChannel;
-}
-
-var subresourcePaths = [
- [ "/index.html", "index.html" ],
- [ "index.html", "index.html" ],
- [ "/../../index.html", "index.html" ],
- [ "../../index.html", "index.html" ],
- [ "/hello/./.././index.html", "index.html" ],
- [ "hello/./.././index.html", "index.html" ],
- [ "../hello/index.html", "hello/index.html" ],
- [ "/../hello/index.html", "hello/index.html" ],
- [ "/./././index.html", "index.html" ],
-]
-
-var content = "<html><body> Test </body></html>";
-
-// The package content
-// getData formats it as described at http://www.w3.org/TR/web-packaging/#streamable-package-format
-var testData = {
- token : "gc0pJq0M:08jU534c0p",
- getData: function() {
- var str = "";
-
- str += "--" + this.token + "\r\n";
- str += "Content-Location: " + subresourcePaths[gRequestNo][0] + "\r\n";
- str += "Content-Type: text/html" + "\r\n";
- str += "\r\n";
-
- str += content + "\r\n";
- str += "--" + this.token + "--";
-
- return str;
- }
-}
-
-XPCOMUtils.defineLazyGetter(this, "uri", function() {
- return "http://localhost:" + httpserver.identity.primaryPort;
-});
-
-// The active http server initialized in run_test
-var httpserver = null;
-// The packaged app service initialized in run_test
-var paservice = null;
-// This variable is set before getResource is called. The listener uses this variable
-// to check the correct resource path for the returned entry
-var packagePath = null;
-
-function run_test()
-{
- // setup test
- httpserver = new HttpServer();
- httpserver.registerPrefixHandler("/package/", packagedAppContentHandler);
- httpserver.start(-1);
-
- paservice = Cc["@mozilla.org/network/packaged-app-service;1"]
- .getService(Ci.nsIPackagedAppService);
-
- var testuri = createURI("http://localhost/");
-
- add_test(continueTest);
- // run tests
- run_next_test();
-}
-
-// A listener we use to check the proper cache entry is returned by the service
-function packagedResourceListener(path, content) {
- this.path = path;
- this.content = content;
-}
-
-packagedResourceListener.prototype = {
- QueryInterface: function (iid) {
- if (iid.equals(Ci.nsICacheEntryOpenCallback) ||
- iid.equals(Ci.nsISupports))
- return this;
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
- onCacheEntryCheck: function() { return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; },
- onCacheEntryAvailable: function (entry, isnew, appcache, status) {
- equal(status, Cr.NS_OK, "status is NS_OK");
- ok(!!entry, "Needs to have an entry");
- equal(entry.key, uri + packagePath + "!//" + this.path, "Check entry has correct name");
- var inputStream = entry.openInputStream(0);
- pumpReadStream(inputStream, (read) => {
- inputStream.close();
- equal(read, this.content); // not using do_check_eq since logger will fail for the 1/4MB string
- continueTest();
- });
- }
-};
-
-var gGenerator = test_paths();
-function continueTest() {
- try {
- gGenerator.next();
- } catch (e if e instanceof StopIteration) {
- run_next_test();
- }
-}
-function test_paths() {
- for (var i in subresourcePaths) {
- packagePath = "/package/" + i;
- dump("Iteration " + i + "\n");
- let url = uri + packagePath + "!//" + subresourcePaths[i][1];
- paservice.getResource(getChannelForURL(url),
- new packagedResourceListener(subresourcePaths[i][1], content));
- yield undefined;
- }
-}
deleted file mode 100644
--- a/netwerk/test/unit/test_packaged_app_utils.js
+++ /dev/null
@@ -1,143 +0,0 @@
-const header_missing_signature = "header1: content1";
-const header_invalid_signature = "header1: content1\r\nmanifest-signature: invalid-signature\r\n";
-const header = "manifest-signature: MIIF1AYJKoZIhvcNAQcCoIIFxTCCBcECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCA54wggOaMIICgqADAgECAgEEMA0GCSqGSIb3DQEBCwUAMHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEkMCIGA1UEChMbRXhhbXBsZSBUcnVzdGVkIENvcnBvcmF0aW9uMRkwFwYDVQQDExBUcnVzdGVkIFZhbGlkIENBMB4XDTE1MTExOTAzMDEwNVoXDTM1MTExOTAzMDEwNVowdDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGjAYBgNVBAMTEVRydXN0ZWQgQ29ycCBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzPback9X7RRxKTc3/5o2vm9Ro6XNiSM9NPsN3djjCIVz50bY0rJkP98zsqpFjnLwqHeJigxyYoqFexRhRLgKrG10CxNl4rxP6CEPENjvj5FfbX/HUZpT/DelNR18F498yD95vSHcSrCc3JrjV3bKA+wgt11E4a0Ba95S1RuwtehZw1+Y4hO8nHpbSGfjD0BpluFY2nDoYAm+aWSrsmLuJsKLO8Xn2I1brZFJUynR3q1ujuDE9EJk1niDLfOeVgXM4AavJS5C0ZBHhAhR2W+K9NN97jpkpmHFqecTwDXB7rEhsyB3185cI7anaaQfHHfH5+4SD+cMDNtYIOSgLO06ZwIDAQABozgwNjAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAlnVyLz5dPhS0ZhZD6qJOUzSo6nFwMxNX1m0oS37mevtuh0b0o1gmEuMw3mVxiAVkC2vPsoxBL2wLlAkcEdBPxGEqhBmtiBY3F3DgvEkf+/sOY1rnr6O1qLZuBAnPzA1Vnco8Jwf0DYF0PxaRd8yT5XSl5qGpM2DItEldZwuKKaL94UEgIeC2c+Uv/IOyrv+EyftX96vcmRwr8ghPFLQ+36H5nuAKEpDD170EvfWl1zs0dUPiqSI6l+hy5V14gl63Woi34L727+FKx8oatbyZtdvbeeOmenfTLifLomnZdx+3WMLkp3TLlHa5xDLwifvZtBP2d3c6zHp7gdrGU1u2WTGCAf4wggH6AgEBMHgwczELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFRydXN0ZWQgVmFsaWQgQ0ECAQQwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE1MTExOTAzMDEyM1owIwYJKoZIhvcNAQkEMRYEFJ7c42bSAcIZOL+r8PIsMNAXByYiMA0GCSqGSIb3DQEBAQUABIIBABPrgGwvi9bwgUEqiL9I0UpQsEEjzNvID9iSt9cicB3exQ9z3H2b47P7HOWicdYI4OQ1Gb+1OjGWJWoBbOuF+ty4HNIMlLiq+Mhm82J2fTA9h8v9BohjvjwMSECJHFQR1pp6veCrWqIvkhHLX/GcGZIr5vBmkpkcMpWKT/N8VmuNu/DKHtKiTianAWnFguAruOeL02MfKlg8mNLCQysd6qj5mbLhTvR7mtn6XaRFrHB4VSfYPerzP71/AzhVqlPRLIYQocSkRoAE+eNeMcP6RcEinKRqK0SxqmRWeSiJpkDm+5Hlx7Xs8Qamqiteyr8FN7VjkGByM0IcpH6Bd5h3trQ=\r\n";
-
-const manifest = "Content-Location: manifest.webapp\r\n" +
- "Content-Type: application/x-web-app-manifest+json\r\n\r\n" +
-`{
- "moz-package-origin": "http://mochi.test:8888",
- "name": "My App",
- "moz-resources": [
- {
- "src": "page2.html",
- "integrity": "JREF3JbXGvZ+I1KHtoz3f46ZkeIPrvXtG4VyFQrJ7II="
- },
- {
- "src": "index.html",
- "integrity": "IjQ2S/V9qsC7wW5uv/Niq40M1aivvqH5+1GKRwUnyRg="
- },
- {
- "src": "scripts/script.js",
- "integrity": "6TqtNArQKrrsXEQWu3D9ZD8xvDRIkhyV6zVdTcmsT5Q="
- },
- {
- "src": "scripts/library.js",
- "integrity": "TN2ByXZiaBiBCvS4MeZ02UyNi44vED+KjdjLInUl4o8="
- }
- ],
- "moz-permissions": [
- {
- "systemXHR": {
- "description": "Needed to download stuff"
- },
- "devicestorage:pictures": {
- "description": "Need to load pictures"
- }
- }
- ],
- "package-identifier": "611FC2FE-491D-4A47-B3B3-43FBDF6F404F",
- "description": "A great app!"
-}`;
-
-const manifest_missing_moz_resources = "Content-Location: manifest.webapp\r\n" +
- "Content-Type: application/x-web-app-manifest+json\r\n\r\n" +
-`{
- "name": "My App",
- "moz-permissions": [
- {
- "systemXHR": {
- "description": "Needed to download stuff"
- },
- "devicestorage:pictures": {
- "description": "Need to load pictures"
- }
- }
- ],
- "moz-uuid": "some-uuid",
- "moz-package-location": "https://example.com/myapp/app.pak",
- "description": "A great app!"
-}`;
-
-const manifest_malformed_json = "}";
-
-var packagedAppUtils;
-
-function run_test() {
- add_test(test_verify_manifest(header_missing_signature, manifest, false));
- add_test(test_verify_manifest(header_invalid_signature, manifest, false));
- add_test(test_verify_manifest(header, manifest_malformed_json, false));
- add_test(test_verify_manifest(header, manifest_missing_moz_resources, false));
- add_test(test_verify_manifest(header, manifest, true));
-
- // The last verification must succeed, because check_integrity use that object;
- add_test(test_check_integrity_success);
- add_test(test_check_integrity_filename_not_matched);
- add_test(test_check_integrity_hashvalue_not_matched);
-
- run_next_test();
-}
-
-function test_verify_manifest(aHeader, aManifest, aShouldSucceed) {
- return function() {
- do_test_pending();
- packagedAppUtils = Cc["@mozilla.org/network/packaged-app-utils;1"].
- createInstance(Ci.nsIPackagedAppUtils);
- let fakeVerifier = {
- fireVerifiedEvent: function(aForManifest, aSuccess) {
- ok(aForManifest, "aForManifest should be true");
- equal(aSuccess, aShouldSucceed, "Expected verification result: " + aShouldSucceed);
-
- // Verify packageIdentifier if it's a successful verification.
- if (aShouldSucceed) {
- equal(packagedAppUtils.packageIdentifier,
- '611FC2FE-491D-4A47-B3B3-43FBDF6F404F',
- 'package identifier');
- }
-
- do_test_finished();
- run_next_test();
- }
- };
- packagedAppUtils.verifyManifest(aHeader, aManifest, fakeVerifier, false);
- }
-}
-
-function test_check_integrity_success() {
- let manifestBody = manifest.substr(manifest.indexOf('\r\n\r\n') + 4);
- fakeVerifier = {
- fireVerifiedEvent: function(aForManifest, aSuccess) {
- ok(!aForManifest && aSuccess, "checkIntegrity should succeed");
- do_test_finished();
- run_next_test();
- }
- };
- for (let resource of JSON.parse(manifestBody)["moz-resources"]) {
- do_test_pending();
- packagedAppUtils.checkIntegrity(resource.src, resource.integrity, fakeVerifier);
- }
-}
-
-function test_check_integrity_filename_not_matched() {
- fakeVerifier = {
- fireVerifiedEvent: function(aForManifest, aSuccess) {
- ok(!aForManifest && !aSuccess, "checkIntegrity should fail");
- do_test_finished();
- run_next_test();
- }
- };
- do_test_pending();
- packagedAppUtils.checkIntegrity("/nosuchfile.html", "sha256-kass...eoirW-e", fakeVerifier);
- run_next_test();
-}
-
-function test_check_integrity_hashvalue_not_matched() {
- fakeVerifier = {
- fireVerifiedEvent: function(aForManifest, aSuccess) {
- ok(!aForManifest && !aSuccess, "checkIntegrity should fail");
- do_test_finished();
- run_next_test();
- }
- };
- do_test_pending();
- packagedAppUtils.checkIntegrity("/index.html", "kass...eoirW-e", fakeVerifier);
-}
deleted file mode 100644
--- a/netwerk/test/unit/test_packaged_app_verifier.js
+++ /dev/null
@@ -1,228 +0,0 @@
-//
-// This file tests the packaged app verifier - nsIPackagedAppVerifier
-//
-// ----------------------------------------------------------------------------
-//
-// All the test cases will ensure the callback order and args are exact the
-// same as how and what we feed into the verifier. We also check if verifier
-// gives the correct verification result like "is package signed", the
-// "package origin", etc.
-//
-// Note that the actual signature verification is not done yet. If we claim a
-// non-empty signature, the verifier will regard the verification as failed.
-// The actual verification process is addressed by Bug 1178518. Non-developer mode
-// test cases have to be modified once Bug 1178518 lands.
-//
-// We also test the developer mode here. In developer mode, no matter what kind
-// of signautre do we initialize the verifier, the package is always said signed.
-//
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-////////////////////////////////////////////////////////////////
-var gIoService = Cc["@mozilla.org/network/io-service;1"]
- .getService(Ci.nsIIOService);
-
-var gPrefs = Cc["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
-
-var gVerifier = Cc["@mozilla.org/network/packaged-app-verifier;1"]
- .createInstance(Ci.nsIPackagedAppVerifier);
-
-var gCacheStorageService = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);;
-
-var gLoadContextInfoFactory =
- Cu.import("resource://gre/modules/LoadContextInfo.jsm", {}).LoadContextInfo;
-
-const kUriIdx = 0;
-const kStatusCodeIdx = 1;
-const kVerificationSuccessIdx = 2;
-const kContentIdx = 3;
-
-function createVerifierListener(aExpecetedCallbacks,
- aExpectedPackageId,
- aExpectedIsSigned,
- aPackageCacheEntry) {
- let cnt = 0;
-
- return {
- onVerified: function(aIsManifest,
- aUri,
- aCacheEntry,
- aStatusCode,
- aIsLastPart,
- aVerificationSuccess) {
- cnt++;
-
- let expectedCallback = aExpecetedCallbacks[cnt - 1];
- let isManifest = (cnt === 1);
- let isLastPart = (cnt === aExpecetedCallbacks.length);
-
- // Check if we are called back with correct info.
- equal(aIsManifest, isManifest, 'is manifest');
- equal(aUri.asciiSpec, expectedCallback[kUriIdx], 'URL');
- equal(aStatusCode, expectedCallback[kStatusCodeIdx], 'status code');
- equal(aIsLastPart, isLastPart, 'is lastPart');
- equal(aVerificationSuccess, expectedCallback[kVerificationSuccessIdx], 'verification result');
-
- if (isManifest) {
- // Check if the verifier got the right package info.
- equal(gVerifier.packageIdentifier, aExpectedPackageId, 'package identifier');
- equal(gVerifier.isPackageSigned, aExpectedIsSigned, 'is package signed');
-
- // Check if the verifier wrote the signed package origin to the cache.
- ok(!!aPackageCacheEntry, aPackageCacheEntry.key);
- let signePakIdInCache = aPackageCacheEntry.getMetaDataElement('package-id');
- equal(signePakIdInCache,
- (aExpectedIsSigned ? aExpectedPackageId : ''),
- 'package-id in cache');
- }
-
- if (isLastPart) {
- run_next_test();
- }
- },
- };
-};
-
-function feedData(aString) {
- let stringStream = Cc["@mozilla.org/io/string-input-stream;1"].
- createInstance(Ci.nsIStringInputStream);
- stringStream.setData(aString, aString.length);
- gVerifier.onDataAvailable(null, null, stringStream, 0, aString.length);
-}
-
-function feedResources(aExpectedCallbacks, aSignature) {
- for (let i = 0; i < aExpectedCallbacks.length; i++) {
- let expectedCallback = aExpectedCallbacks[i];
- let isLastPart = (i === aExpectedCallbacks.length - 1);
-
- // Start request.
- let uri = gIoService.newURI(expectedCallback[kUriIdx], null, null);
- gVerifier.onStartRequest(null, uri);
-
- // Feed data at once.
- let contentString = expectedCallback[kContentIdx];
- if (contentString !== undefined) {
- feedData(contentString);
- }
-
- // Stop request.
- let info = gVerifier.createResourceCacheInfo(uri,
- null,
- expectedCallback[kStatusCodeIdx],
- isLastPart);
-
- gVerifier.onStopRequest(null, info, expectedCallback[kStatusCodeIdx]);
- }
-}
-
-function createPackageCache(aPackageUriAsAscii, aLoadContextInfo) {
- let cacheStorage =
- gCacheStorageService.memoryCacheStorage(aLoadContextInfo);
-
- let uri = gIoService.newURI(aPackageUriAsAscii, null, null);
- return cacheStorage.openTruncate(uri, '');
-}
-
-function test_no_signature(aBypassVerification) {
- const kOrigin = 'http://foo.com';
-
- aBypassVerification = !!aBypassVerification;
-
- // If the package has no signature, the package is unsigned
- // but the verification result is always true.
-
- const expectedCallbacks = [
- // URL statusCode verificationResult
- [kOrigin + '/manifest', Cr.NS_OK, true],
- [kOrigin + '/1.html', Cr.NS_OK, true],
- [kOrigin + '/2.js', Cr.NS_OK, true],
- [kOrigin + '/3.jpg', Cr.NS_OK, true],
- [kOrigin + '/4.html', Cr.NS_OK, true],
- [kOrigin + '/5.css', Cr.NS_OK, true],
- ];
-
- let isPackageSigned = false;
-
- // We only require the package URL to be different in each test case.
- let packageUriString = kOrigin + '/pak' + (aBypassVerification ? '-dev' : '');
-
- let packageCacheEntry =
- createPackageCache(packageUriString, gLoadContextInfoFactory.default);
-
- let verifierListener = createVerifierListener(expectedCallbacks,
- '',
- isPackageSigned,
- packageCacheEntry);
-
- gVerifier.init(verifierListener, kOrigin, '', packageCacheEntry);
-
- feedResources(expectedCallbacks, '');
-}
-
-function test_invalid_signature(aBypassVerification) {
- const kOrigin = 'http://bar.com';
-
- aBypassVerification = !!aBypassVerification;
-
- // Since we haven't implemented signature verification, the verification always
- // fails if the signature exists.
-
- let verificationResult = aBypassVerification; // Verification always success in developer mode.
- let isPackageSigned = aBypassVerification; // Package is always considered as signed in developer mode.
-
- const kPackagedId = '611FC2FE-491D-4A47-B3B3-43FBDF6F404F';
- const kManifestContent = 'Content-Location: manifest.webapp\r\n' +
- 'Content-Type: application/x-web-app-manifest+json\r\n' +
- '\r\n' +
- '{ "package-identifier": "' + kPackagedId + '",\n' +
- ' "moz-package-origin": "' + kOrigin + '" }';
-
- const expectedCallbacks = [
- // URL statusCode verificationResult content
- [kOrigin + '/manifest', Cr.NS_OK, verificationResult, kManifestContent],
- [kOrigin + '/1.html', Cr.NS_OK, verificationResult, 'abc'],
- [kOrigin + '/2.js', Cr.NS_OK, verificationResult, 'abc'],
- [kOrigin + '/3.jpg', Cr.NS_OK, verificationResult, 'abc'],
- [kOrigin + '/4.html', Cr.NS_OK, verificationResult, 'abc'],
- [kOrigin + '/5.css', Cr.NS_OK, verificationResult, 'abc'],
- ];
-
- let packageUriString = kOrigin + '/pak' + (aBypassVerification ? '-dev' : '');
- let packageCacheEntry =
- createPackageCache(packageUriString, gLoadContextInfoFactory.private);
-
- let verifierListener = createVerifierListener(expectedCallbacks,
- aBypassVerification ? kPackagedId : '',
- isPackageSigned,
- packageCacheEntry);
-
- let signature = 'manifest-signature: 11111111111111111111111';
- gVerifier.init(verifierListener, kOrigin, signature, packageCacheEntry);
-
- feedResources(expectedCallbacks, signature);
-}
-
-function test_invalid_signature_bypass_verification() {
- let pref = "network.http.signed-packages.trusted-origin";
- ok(!!Ci.nsISupportsString, "Ci.nsISupportsString");
- let origin = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
- origin.data = "http://bar.com";
- gPrefs.setComplexValue(pref, Ci.nsISupportsString, origin);
- test_invalid_signature(true);
- gPrefs.clearUserPref(pref);
-}
-
-function run_test()
-{
- ok(!!gVerifier);
-
- add_test(test_no_signature);
- add_test(test_invalid_signature);
- add_test(test_invalid_signature_bypass_verification);
-
- // run tests
- run_next_test();
-}
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -18,17 +18,16 @@ support-files =
data/test_readline7.txt
data/test_readline8.txt
data/signed_win.exe
socks_client_subprocess.js
test_link.desktop
test_link.url
../../dns/effective_tld_names.dat
-[test_packaged_app_channel.js]
[test_nsIBufferedOutputStream_writeFrom_block.js]
[test_cache2-00-service-get.js]
[test_cache2-01-basic.js]
[test_cache2-01a-basic-readonly.js]
[test_cache2-01b-basic-datasize.js]
[test_cache2-01c-basic-hasmeta-only.js]
[test_cache2-01d-basic-not-wanted.js]
[test_cache2-01e-basic-bypass-if-busy.js]
@@ -341,28 +340,23 @@ skip-if = os == "android" || (os == "win
reason = bug 1190674
firefox-appdir = browser
[test_tls_server_multiple_clients.js]
# The local cert service used by this test is not currently shipped on Android
skip-if = os == "android"
[test_1073747.js]
[test_multipart_streamconv_application_package.js]
[test_safeoutputstream_append.js]
-[test_packaged_app_service.js]
-[test_packaged_app_verifier.js]
-[test_packaged_app_utils.js]
[test_suspend_channel_before_connect.js]
[test_inhibit_caching.js]
[test_dns_disable_ipv4.js]
[test_dns_disable_ipv6.js]
-[test_packaged_app_service_paths.js]
[test_bug1195415.js]
[test_cookie_blacklist.js]
[test_getHost.js]
-[test_packaged_app_bug1214079.js]
[test_bug412457.js]
[test_bug464591.js]
[test_alt-data_simple.js]
[test_alt-data_stream.js]
[test_cache-control_request.js]
[test_bug1279246.js]
[test_throttlequeue.js]
[test_throttlechannel.js]