browser/devtools/app-manager/app-validator.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 "use strict";
michael@0 5
michael@0 6 let {Ci,Cu,CC} = require("chrome");
michael@0 7 const promise = require("devtools/toolkit/deprecated-sync-thenables");
michael@0 8
michael@0 9 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
michael@0 10 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
michael@0 11 let XMLHttpRequest = CC("@mozilla.org/xmlextras/xmlhttprequest;1");
michael@0 12 let strings = Services.strings.createBundle("chrome://browser/locale/devtools/app-manager.properties");
michael@0 13
michael@0 14 function AppValidator(project) {
michael@0 15 this.project = project;
michael@0 16 this.errors = [];
michael@0 17 this.warnings = [];
michael@0 18 }
michael@0 19
michael@0 20 AppValidator.prototype.error = function (message) {
michael@0 21 this.errors.push(message);
michael@0 22 };
michael@0 23
michael@0 24 AppValidator.prototype.warning = function (message) {
michael@0 25 this.warnings.push(message);
michael@0 26 };
michael@0 27
michael@0 28 AppValidator.prototype._getPackagedManifestFile = function () {
michael@0 29 let manifestFile = FileUtils.File(this.project.location);
michael@0 30 if (!manifestFile.exists()) {
michael@0 31 this.error(strings.GetStringFromName("validator.nonExistingFolder"));
michael@0 32 return null;
michael@0 33 }
michael@0 34 if (!manifestFile.isDirectory()) {
michael@0 35 this.error(strings.GetStringFromName("validator.expectProjectFolder"));
michael@0 36 return null;
michael@0 37 }
michael@0 38 manifestFile.append("manifest.webapp");
michael@0 39 if (!manifestFile.exists() || !manifestFile.isFile()) {
michael@0 40 this.error(strings.GetStringFromName("validator.wrongManifestFileName"));
michael@0 41 return null;
michael@0 42 }
michael@0 43 return manifestFile;
michael@0 44 };
michael@0 45
michael@0 46 AppValidator.prototype._getPackagedManifestURL = function () {
michael@0 47 let manifestFile = this._getPackagedManifestFile();
michael@0 48 if (!manifestFile) {
michael@0 49 return null;
michael@0 50 }
michael@0 51 return Services.io.newFileURI(manifestFile).spec;
michael@0 52 };
michael@0 53
michael@0 54 AppValidator.prototype._fetchManifest = function (manifestURL) {
michael@0 55 let deferred = promise.defer();
michael@0 56 this.manifestURL = manifestURL;
michael@0 57
michael@0 58 let req = new XMLHttpRequest();
michael@0 59 try {
michael@0 60 req.open("GET", manifestURL, true);
michael@0 61 } catch(e) {
michael@0 62 this.error(strings.formatStringFromName("validator.invalidManifestURL", [manifestURL], 1));
michael@0 63 deferred.resolve(null);
michael@0 64 return deferred.promise;
michael@0 65 }
michael@0 66 req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING;
michael@0 67 req.onload = (function () {
michael@0 68 let manifest = null;
michael@0 69 try {
michael@0 70 manifest = JSON.parse(req.responseText);
michael@0 71 } catch(e) {
michael@0 72 this.error(strings.formatStringFromName("validator.invalidManifestJSON", [e, manifestURL], 2));
michael@0 73 }
michael@0 74 deferred.resolve(manifest);
michael@0 75 }).bind(this);
michael@0 76 req.onerror = (function () {
michael@0 77 this.error(strings.formatStringFromName("validator.noAccessManifestURL", [req.statusText, manifestURL], 2));
michael@0 78 deferred.resolve(null);
michael@0 79 }).bind(this);
michael@0 80
michael@0 81 try {
michael@0 82 req.send(null);
michael@0 83 } catch(e) {
michael@0 84 this.error(strings.formatStringFromName("validator.noAccessManifestURL", [e, manifestURL], 2));
michael@0 85 deferred.resolve();
michael@0 86 }
michael@0 87
michael@0 88 return deferred.promise;
michael@0 89 };
michael@0 90
michael@0 91 AppValidator.prototype._getManifest = function () {
michael@0 92 let manifestURL;
michael@0 93 if (this.project.type == "packaged") {
michael@0 94 manifestURL = this._getPackagedManifestURL();
michael@0 95 if (!manifestURL)
michael@0 96 return promise.resolve(null);
michael@0 97 } else if (this.project.type == "hosted") {
michael@0 98 manifestURL = this.project.location;
michael@0 99 try {
michael@0 100 Services.io.newURI(manifestURL, null, null);
michael@0 101 } catch(e) {
michael@0 102 this.error(strings.formatStringFromName("validator.invalidHostedManifestURL", [manifestURL, e.message]));
michael@0 103 return promise.resolve(null);
michael@0 104 }
michael@0 105 } else {
michael@0 106 this.error(strings.formatStringFromName("validator.invalidProjectType", [this.project.type], 1));
michael@0 107 return promise.resolve(null);
michael@0 108 }
michael@0 109 return this._fetchManifest(manifestURL);
michael@0 110 };
michael@0 111
michael@0 112 AppValidator.prototype.validateManifest = function (manifest) {
michael@0 113 if (!manifest.name) {
michael@0 114 this.error(strings.GetStringFromName("validator.missNameManifestProperty"));
michael@0 115 }
michael@0 116
michael@0 117 if (!manifest.icons || Object.keys(manifest.icons).length === 0) {
michael@0 118 this.warning(strings.GetStringFromName("validator.missIconsManifestProperty"));
michael@0 119 } else if (!manifest.icons["128"]) {
michael@0 120 this.warning(strings.GetStringFromName("validator.missIconMarketplace"));
michael@0 121 }
michael@0 122 };
michael@0 123
michael@0 124 AppValidator.prototype._getOriginURL = function () {
michael@0 125 if (this.project.type == "packaged") {
michael@0 126 let manifestURL = Services.io.newURI(this.manifestURL, null, null);
michael@0 127 return Services.io.newURI(".", null, manifestURL).spec;
michael@0 128 } else if (this.project.type == "hosted") {
michael@0 129 return Services.io.newURI(this.project.location, null, null).prePath;
michael@0 130 }
michael@0 131 };
michael@0 132
michael@0 133 AppValidator.prototype.validateLaunchPath = function (manifest) {
michael@0 134 let deferred = promise.defer();
michael@0 135 // The launch_path field has to start with a `/`
michael@0 136 if (manifest.launch_path && manifest.launch_path[0] !== "/") {
michael@0 137 this.error(strings.formatStringFromName("validator.nonAbsoluteLaunchPath", [manifest.launch_path], 1));
michael@0 138 deferred.resolve();
michael@0 139 return deferred.promise;
michael@0 140 }
michael@0 141 let origin = this._getOriginURL();
michael@0 142 let path;
michael@0 143 if (this.project.type == "packaged") {
michael@0 144 path = "." + ( manifest.launch_path || "/index.html" );
michael@0 145 } else if (this.project.type == "hosted") {
michael@0 146 path = manifest.launch_path || "/";
michael@0 147 }
michael@0 148 let indexURL;
michael@0 149 try {
michael@0 150 indexURL = Services.io.newURI(path, null, Services.io.newURI(origin, null, null)).spec;
michael@0 151 } catch(e) {
michael@0 152 this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [origin + path], 1));
michael@0 153 deferred.resolve();
michael@0 154 return deferred.promise;
michael@0 155 }
michael@0 156
michael@0 157 let req = new XMLHttpRequest();
michael@0 158 try {
michael@0 159 req.open("HEAD", indexURL, true);
michael@0 160 } catch(e) {
michael@0 161 this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [indexURL], 1));
michael@0 162 deferred.resolve();
michael@0 163 return deferred.promise;
michael@0 164 }
michael@0 165 req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING;
michael@0 166 req.onload = () => {
michael@0 167 if (req.status >= 400)
michael@0 168 this.error(strings.formatStringFromName("validator.accessFailedLaunchPathBadHttpCode", [indexURL, req.status], 2));
michael@0 169 deferred.resolve();
michael@0 170 };
michael@0 171 req.onerror = () => {
michael@0 172 this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [indexURL], 1));
michael@0 173 deferred.resolve();
michael@0 174 };
michael@0 175
michael@0 176 try {
michael@0 177 req.send(null);
michael@0 178 } catch(e) {
michael@0 179 this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [indexURL], 1));
michael@0 180 deferred.resolve();
michael@0 181 }
michael@0 182
michael@0 183 return deferred.promise;
michael@0 184 };
michael@0 185
michael@0 186 AppValidator.prototype.validateType = function (manifest) {
michael@0 187 let appType = manifest.type || "web";
michael@0 188 if (["web", "privileged", "certified"].indexOf(appType) === -1) {
michael@0 189 this.error(strings.formatStringFromName("validator.invalidAppType", [appType], 1));
michael@0 190 } else if (this.project.type == "hosted" &&
michael@0 191 ["certified", "privileged"].indexOf(appType) !== -1) {
michael@0 192 this.error(strings.formatStringFromName("validator.invalidHostedPriviledges", [appType], 1));
michael@0 193 }
michael@0 194
michael@0 195 // certified app are not fully supported on the simulator
michael@0 196 if (appType === "certified") {
michael@0 197 this.warning(strings.GetStringFromName("validator.noCertifiedSupport"));
michael@0 198 }
michael@0 199 };
michael@0 200
michael@0 201 AppValidator.prototype.validate = function () {
michael@0 202 this.errors = [];
michael@0 203 this.warnings = [];
michael@0 204 return this._getManifest().
michael@0 205 then((function (manifest) {
michael@0 206 if (manifest) {
michael@0 207 this.manifest = manifest;
michael@0 208 this.validateManifest(manifest);
michael@0 209 this.validateType(manifest);
michael@0 210 return this.validateLaunchPath(manifest);
michael@0 211 }
michael@0 212 }).bind(this));
michael@0 213 };
michael@0 214
michael@0 215 exports.AppValidator = AppValidator;

mercurial