From c3dabcbd2b578a6515ee8537ce16d83377f89fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrice=20Desr=C3=A9?= Date: Mon, 10 Dec 2012 15:48:59 -0800 Subject: [PATCH] Bug 796198 - Use the right cookie jar when downloading package and minimanifest for packaged apps - Part 1: move the xhr to Webapps.jsm [r=sicking] --- dom/apps/src/Webapps.js | 161 +++++++++------------------------------ dom/apps/src/Webapps.jsm | 120 ++++++++++++++++++++++++++++- 2 files changed, 153 insertions(+), 128 deletions(-) diff --git a/dom/apps/src/Webapps.js b/dom/apps/src/Webapps.js index 4f2055270cbb..f7071ffa98a1 100644 --- a/dom/apps/src/Webapps.js +++ b/dom/apps/src/Webapps.js @@ -34,14 +34,6 @@ function WebappsRegistry() { WebappsRegistry.prototype = { __proto__: DOMRequestIpcHelper.prototype, - // Hosted apps can't be trusted or certified, so just check that the - // manifest doesn't ask for those. - checkAppStatus: function(aManifest) { - let manifestStatus = aManifest.type || "web"; - return (Services.prefs.getBoolPref("dom.mozApps.dev_mode") || - manifestStatus === "web"); - }, - receiveMessage: function(aMessage) { let msg = aMessage.json; if (msg.oid != this._id) @@ -96,66 +88,27 @@ WebappsRegistry.prototype = { this._validateScheme(aURL); let installURL = this._window.location.href; - let installOrigin = this._getOrigin(installURL); let request = this.createRequest(); let requestID = this.getRequestId(request); - let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest); - xhr.open("GET", aURL, true); - xhr.channel.loadFlags |= Ci.nsIRequest.VALIDATE_ALWAYS; + let receipts = (aParams && aParams.receipts && + Array.isArray(aParams.receipts)) ? aParams.receipts + : []; + let categories = (aParams && aParams.categories && + Array.isArray(aParams.categories)) ? aParams.categories + : []; - xhr.addEventListener("load", (function() { - if (xhr.status == 200) { - if (!AppsUtils.checkManifestContentType(installOrigin, this._getOrigin(aURL), - xhr.getResponseHeader("content-type"))) { - Services.DOMRequest.fireError(request, "INVALID_MANIFEST"); - return; - } - - let manifest; - try { - manifest = JSON.parse(xhr.responseText, installOrigin); - } catch (e) { - Services.DOMRequest.fireError(request, "MANIFEST_PARSE_ERROR"); - Cu.reportError("Error installing app from: " + installOrigin + ": " + "MANIFEST_PARSE_ERROR"); - return; - } - - if (!AppsUtils.checkManifest(manifest)) { - Services.DOMRequest.fireError(request, "INVALID_MANIFEST"); - Cu.reportError("Error installing app from: " + installOrigin + ": " + "INVALID_MANIFEST"); - } else if (!AppsUtils.checkInstallAllowed(manifest, installOrigin)) { - Services.DOMRequest.fireError(request, "INSTALL_FROM_DENIED"); - Cu.reportError("Error installing app from: " + installOrigin + ": " + "INSTALL_FROM_DENIED"); - } else if (!this.checkAppStatus(manifest)) { - Services.DOMRequest.fireError(request, "INVALID_SECURITY_LEVEL"); - Cu.reportError("Error installing app, '" + manifest.name + "': " + "INVALID_SECURITY_LEVEL"); - } else { - let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : []; - let categories = (aParams && aParams.categories && Array.isArray(aParams.categories)) ? aParams.categories : []; - let etag = xhr.getResponseHeader("Etag"); - cpmm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin, - origin: this._getOrigin(aURL), - manifestURL: aURL, - manifest: manifest, - etag: etag, - receipts: receipts, - categories: categories }, - from: installURL, - oid: this._id, - requestID: requestID }); - } - } else { - Services.DOMRequest.fireError(request, "MANIFEST_URL_ERROR"); - Cu.reportError("Error installing app from: " + installOrigin + ": " + "MANIFEST_URL_ERROR"); - } - }).bind(this), false); - - xhr.addEventListener("error", (function() { - Services.DOMRequest.fireError(request, "NETWORK_ERROR"); - Cu.reportError("Error installing app from: " + installOrigin + ": " + "NETWORK_ERROR"); - }).bind(this), false); - - xhr.send(null); + cpmm.sendAsyncMessage("Webapps:Install", + { app: { + installOrigin: this._getOrigin(installURL), + origin: this._getOrigin(aURL), + manifestURL: aURL, + receipts: receipts, + categories: categories + }, + from: installURL, + oid: this._id, + requestID: requestID + }); return request; }, @@ -203,73 +156,31 @@ WebappsRegistry.prototype = { // mozIDOMApplicationRegistry2 implementation installPackage: function(aURL, aParams) { - let installURL = this._window.location.href; - let installOrigin = this._getOrigin(installURL); this._validateScheme(aURL); + let installURL = this._window.location.href; let request = this.createRequest(); let requestID = this.getRequestId(request); - let receipts = (aParams && aParams.receipts && - Array.isArray(aParams.receipts)) ? aParams.receipts : []; + Array.isArray(aParams.receipts)) ? aParams.receipts + : []; let categories = (aParams && aParams.categories && - Array.isArray(aParams.categories)) ? aParams.categories : []; - let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest); - xhr.open("GET", aURL, true); - xhr.channel.loadFlags |= Ci.nsIRequest.VALIDATE_ALWAYS; + Array.isArray(aParams.categories)) ? aParams.categories + : []; - xhr.addEventListener("load", (function() { - if (xhr.status == 200) { - if (!AppsUtils.checkManifestContentType(installOrigin, this._getOrigin(aURL), - xhr.getResponseHeader("content-type"))) { - Services.DOMRequest.fireError(request, "INVALID_MANIFEST"); - return; - } - - let manifest; - try { - manifest = JSON.parse(xhr.responseText, installOrigin); - } catch(e) { - Services.DOMRequest.fireError(request, "MANIFEST_PARSE_ERROR"); - return; - } - if (!(AppsUtils.checkManifest(manifest) && - manifest.package_path)) { - Services.DOMRequest.fireError(request, "INVALID_MANIFEST"); - } else if (!AppsUtils.checkInstallAllowed(manifest, installOrigin)) { - Services.DOMRequest.fireError(request, "INSTALL_FROM_DENIED"); - } else { - if (!this.checkAppStatus(manifest)) { - Services.DOMRequest.fireError(request, "INVALID_SECURITY_LEVEL"); - } else { - let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : []; - let categories = (aParams && aParams.categories && Array.isArray(aParams.categories)) ? aParams.categories : []; - let etag = xhr.getResponseHeader("Etag"); - cpmm.sendAsyncMessage("Webapps:InstallPackage", { app: { - installOrigin: installOrigin, - origin: this._getOrigin(aURL), - manifestURL: aURL, - updateManifest: manifest, - etag: etag, - receipts: receipts, - categories: categories }, - from: installURL, - oid: this._id, - requestID: requestID, - isPackage: true }); - } - } - } - else { - Services.DOMRequest.fireError(request, "MANIFEST_URL_ERROR"); - } - }).bind(this), false); - - xhr.addEventListener("error", (function() { - Services.DOMRequest.fireError(request, "NETWORK_ERROR"); - }).bind(this), false); - - xhr.send(null); + cpmm.sendAsyncMessage("Webapps:InstallPackage", + { app: { + installOrigin: this._getOrigin(installURL), + origin: this._getOrigin(aURL), + manifestURL: aURL, + receipts: receipts, + categories: categories + }, + from: installURL, + oid: this._id, + requestID: requestID, + isPackage: true + }); return request; }, diff --git a/dom/apps/src/Webapps.jsm b/dom/apps/src/Webapps.jsm index 9fea42396131..96ad1053025a 100644 --- a/dom/apps/src/Webapps.jsm +++ b/dom/apps/src/Webapps.jsm @@ -734,7 +734,8 @@ this.DOMApplicationRegistry = { switch (aMessage.name) { case "Webapps:Install": // always ask for UI to install - Services.obs.notifyObservers(mm, "webapps-ask-install", JSON.stringify(msg)); + this.doInstall(msg, mm); + //Services.obs.notifyObservers(mm, "webapps-ask-install", JSON.stringify(msg)); break; case "Webapps:GetSelf": this.getSelf(msg, mm); @@ -761,8 +762,7 @@ this.DOMApplicationRegistry = { mm.sendAsyncMessage("Webapps:GetAll:Return:KO", msg); break; case "Webapps:InstallPackage": - // always ask for UI to install - Services.obs.notifyObservers(mm, "webapps-ask-install", JSON.stringify(msg)); + this.doInstallPackage(msg, mm); break; case "Webapps:GetBasePath": return this.webapps[msg.id].basePath; @@ -1205,6 +1205,120 @@ this.DOMApplicationRegistry = { xhr.send(null); }, + // Downloads the manifest and run checks, then eventually triggers the + // installation UI. + doInstall: function doInstall(aData, aMm) { + let sendError = function sendError(aError) { + aData.error = aError; + aMm.sendAsyncMessage("Webapps:Install:Return:KO", aData); + Cu.reportError("Error installing app from: " + app.installOrigin + + ": " + aError); + }.bind(this); + + // Hosted apps can't be trusted or certified, so just check that the + // manifest doesn't ask for those. + function checkAppStatus(aManifest) { + let manifestStatus = aManifest.type || "web"; + return (Services.prefs.getBoolPref("dom.mozApps.dev_mode") || + manifestStatus === "web"); + } + + let app = aData.app; + + let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(Ci.nsIXMLHttpRequest); + xhr.open("GET", app.manifestURL, true); + xhr.channel.loadFlags |= Ci.nsIRequest.VALIDATE_ALWAYS; + xhr.responseType = "json"; + xhr.addEventListener("load", (function() { + if (xhr.status == 200) { + if (!AppsUtils.checkManifestContentType(app.installOrigin, app.origin, + xhr.getResponseHeader("content-type"))) { + sendError("INVALID_MANIFEST"); + return; + } + + app.manifest = xhr.response; + if (!app.manifest) { + sendError("MANIFEST_PARSE_ERROR"); + return; + } + + if (!AppsUtils.checkManifest(app.manifest)) { + sendError("INVALID_MANIFEST"); + } else if (!AppsUtils.checkInstallAllowed(app.manifest, app.installOrigin)) { + sendError("INSTALL_FROM_DENIED"); + } else if (!checkAppStatus(app.manifest)) { + sendError("INVALID_SECURITY_LEVEL"); + } else { + app.etag = xhr.getResponseHeader("Etag"); + Services.obs.notifyObservers(aMm, "webapps-ask-install", + JSON.stringify(aData)); + } + } else { + sendError("MANIFEST_URL_ERROR"); + } + }).bind(this), false); + + xhr.addEventListener("error", (function() { + sendError("NETWORK_ERROR"); + }).bind(this), false); + + xhr.send(null); + }, + + doInstallPackage: function doInstallPackage(aData, aMm) { + let sendError = function sendError(aError) { + aData.error = aError; + aMm.sendAsyncMessage("Webapps:Install:Return:KO", aData); + Cu.reportError("Error installing packaged app from: " + + app.installOrigin + ": " + aError); + }.bind(this); + + let app = aData.app; + + let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(Ci.nsIXMLHttpRequest); + xhr.open("GET", app.manifestURL, true); + xhr.channel.loadFlags |= Ci.nsIRequest.VALIDATE_ALWAYS; + xhr.responseType = "json"; + + xhr.addEventListener("load", (function() { + if (xhr.status == 200) { + if (!AppsUtils.checkManifestContentType(app.installOrigin, app.origin, + xhr.getResponseHeader("content-type"))) { + sendError("INVALID_MANIFEST"); + return; + } + + let manifest = app.updateManifest = xhr.response; + if (!manifest) { + sendError("MANIFEST_PARSE_ERROR"); + return; + } + if (!(AppsUtils.checkManifest(manifest) && + manifest.package_path)) { + sendError("INVALID_MANIFEST"); + } else if (!AppsUtils.checkInstallAllowed(manifest, app.installOrigin)) { + sendError("INSTALL_FROM_DENIED"); + } else { + app.etag = xhr.getResponseHeader("Etag"); + Services.obs.notifyObservers(aMm, "webapps-ask-install", + JSON.stringify(aData)); + } + } + else { + sendError("MANIFEST_URL_ERROR"); + } + }).bind(this), false); + + xhr.addEventListener("error", (function() { + sendError("NETWORK_ERROR"); + }).bind(this), false); + + xhr.send(null); + }, + denyInstall: function(aData) { let packageId = aData.app.packageId; if (packageId) {