gecko/dom/apps/tests/signed_app.sjs

122 lines
3.6 KiB
JavaScript

var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
// From prio.h
const PR_RDWR = 0x04;
const PR_CREATE_FILE = 0x08;
const PR_TRUNCATE = 0x20;
const CUR_WORK_DIR = "CurWorkD";
Cu.import("resource://gre/modules/NetUtil.jsm");
var gBasePath = "tests/dom/apps/tests/";
var gMiniManifestTemplate = "signed_app_template.webapp";
var gAppName = "Simple App";
var gDevName = "David Clarke";
var gDevUrl = "http://dev.url";
function handleRequest(request, response) {
var query = getQuery(request);
if ("nextApp" in query) {
setState("nextApp", query.nextApp);
response.write("OK");
return;
}
var nextApp = getState("nextApp");
response.setHeader("Access-Control-Allow-Origin", "*", false);
var version = ("version" in query) ? query.version : "1";
var app = ("app" in query) ? query.app : "valid";
var prevVersion = getState("version");
if (version != prevVersion) {
setState("version", version);
}
var packageName = (nextApp.length ? nextApp : app) + "_app_" + version + ".zip";
setState("packageName", packageName);
var packagePath = "/" + gBasePath + "signed/" + packageName;
setState("packagePath", packagePath);
var packageSize = readSize(packagePath);
var etag = getEtag(request, version);
if (!nextApp.length && etagMatches(request, etag)) {
dump("Etags Match. Sending 304\n");
response.setStatusLine(request.httpVersion, "304", "Not modified");
return;
}
response.setHeader("Etag", etag, false);
setState("nextApp", "");
// Serve the mini-manifest corresponding to the requested app version.
var template = gBasePath + gMiniManifestTemplate;
response.setHeader("Content-Type",
"application/x-web-app-manifest+json", false);
var manifest = makeResource(template, version, packagePath, packageSize,
gAppName, gDevName, gDevUrl);
response.write(manifest);
}
function getQuery(request) {
var query = {};
request.queryString.split('&').forEach(function (val) {
var [name, value] = val.split('=');
query[decodeURIComponent(name)] = decodeURIComponent(value);
});
return query;
}
function getEtag(request, version) {
return request.queryString.replace(/[&=]/g, '-') + '-' + version;
}
function etagMatches(request, etag) {
return request.hasHeader("If-None-Match") &&
request.getHeader("If-None-Match") == etag;
}
// File and resources helpers
function readSize(path) {
var file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).get(CUR_WORK_DIR, Ci.nsILocalFile);
var split = path.split("/");
for (var i = 0; i < split.length; ++i) {
file.append(split[i]);
}
return file.fileSize;
}
function readFile(path) {
var file = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get(CUR_WORK_DIR, Ci.nsILocalFile);
var fstream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
var split = path.split("/");
for (var i = 0; i < split.length; ++i) {
file.append(split[i]);
}
fstream.init(file, -1, 0, 0);
var data = NetUtil.readInputStreamToString(fstream, fstream.available());
fstream.close();
return data;
}
function makeResource(templatePath, version, packagePath, packageSize,
appName, developerName, developerUrl) {
var res = readFile(templatePath).
replace(/VERSIONTOKEN/g, version).
replace(/PACKAGEPATHTOKEN/g, packagePath).
replace(/PACKAGESIZETOKEN/g, packageSize).
replace(/NAMETOKEN/g, appName);
return res;
}