1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/apps/tests/signed_app.sjs Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,111 @@ 1.4 +var Cc = Components.classes; 1.5 +var Ci = Components.interfaces; 1.6 +var Cu = Components.utils; 1.7 + 1.8 +// From prio.h 1.9 +const PR_RDWR = 0x04; 1.10 +const PR_CREATE_FILE = 0x08; 1.11 +const PR_TRUNCATE = 0x20; 1.12 + 1.13 +const CUR_WORK_DIR = "CurWorkD"; 1.14 + 1.15 +Cu.import("resource://gre/modules/NetUtil.jsm"); 1.16 + 1.17 +var gBasePath = "tests/dom/apps/tests/"; 1.18 +var gMiniManifestTemplate = "signed_app_template.webapp"; 1.19 +var gAppName = "Simple App"; 1.20 +var gDevName = "David Clarke"; 1.21 +var gDevUrl = "http://dev.url"; 1.22 + 1.23 +function handleRequest(request, response) { 1.24 + var query = getQuery(request); 1.25 + 1.26 + response.setHeader("Access-Control-Allow-Origin", "*", false); 1.27 + 1.28 + var version = ("version" in query) ? query.version : "1"; 1.29 + var app = ("app" in query) ? query.app : "valid"; 1.30 + var prevVersion = getState("version"); 1.31 + 1.32 + if (version != prevVersion) { 1.33 + setState("version", version); 1.34 + } 1.35 + var packageName = app + "_app_" + version + ".zip"; 1.36 + setState("packageName", packageName); 1.37 + var packagePath = "/" + gBasePath + "signed/" + packageName; 1.38 + setState("packagePath", packagePath); 1.39 + var packageSize = readSize(packagePath); 1.40 + 1.41 + var etag = getEtag(request, version); 1.42 + 1.43 + if (etagMatches(request, etag)) { 1.44 + dump("Etags Match. Sending 304\n"); 1.45 + response.setStatusLine(request.httpVersion, "304", "Not modified"); 1.46 + return; 1.47 + } 1.48 + response.setHeader("Etag", etag, false); 1.49 + 1.50 + // Serve the mini-manifest corresponding to the requested app version. 1.51 + var template = gBasePath + gMiniManifestTemplate; 1.52 + 1.53 + response.setHeader("Content-Type", 1.54 + "application/x-web-app-manifest+json", false); 1.55 + var manifest = makeResource(template, version, packagePath, packageSize, 1.56 + gAppName, gDevName, gDevUrl); 1.57 + response.write(manifest); 1.58 +} 1.59 + 1.60 +function getQuery(request) { 1.61 + var query = {}; 1.62 + request.queryString.split('&').forEach(function (val) { 1.63 + var [name, value] = val.split('='); 1.64 + query[decodeURIComponent(name)] = decodeURIComponent(value); 1.65 + }); 1.66 + return query; 1.67 +} 1.68 + 1.69 +function getEtag(request, version) { 1.70 + return request.queryString.replace(/[&=]/g, '-') + '-' + version; 1.71 +} 1.72 + 1.73 +function etagMatches(request, etag) { 1.74 + return request.hasHeader("If-None-Match") && 1.75 + request.getHeader("If-None-Match") == etag; 1.76 +} 1.77 + 1.78 +// File and resources helpers 1.79 + 1.80 +function readSize(path) { 1.81 + var file = Cc["@mozilla.org/file/directory_service;1"]. 1.82 + getService(Ci.nsIProperties).get(CUR_WORK_DIR, Ci.nsILocalFile); 1.83 + var split = path.split("/"); 1.84 + for (var i = 0; i < split.length; ++i) { 1.85 + file.append(split[i]); 1.86 + } 1.87 + return file.fileSize; 1.88 +} 1.89 + 1.90 +function readFile(path) { 1.91 + var file = Cc["@mozilla.org/file/directory_service;1"] 1.92 + .getService(Ci.nsIProperties) 1.93 + .get(CUR_WORK_DIR, Ci.nsILocalFile); 1.94 + var fstream = Cc["@mozilla.org/network/file-input-stream;1"] 1.95 + .createInstance(Ci.nsIFileInputStream); 1.96 + var split = path.split("/"); 1.97 + for (var i = 0; i < split.length; ++i) { 1.98 + file.append(split[i]); 1.99 + } 1.100 + fstream.init(file, -1, 0, 0); 1.101 + var data = NetUtil.readInputStreamToString(fstream, fstream.available()); 1.102 + fstream.close(); 1.103 + return data; 1.104 +} 1.105 + 1.106 +function makeResource(templatePath, version, packagePath, packageSize, 1.107 + appName, developerName, developerUrl) { 1.108 + var res = readFile(templatePath). 1.109 + replace(/VERSIONTOKEN/g, version). 1.110 + replace(/PACKAGEPATHTOKEN/g, packagePath). 1.111 + replace(/PACKAGESIZETOKEN/g, packageSize). 1.112 + replace(/NAMETOKEN/g, appName); 1.113 + return res; 1.114 +}