dom/apps/tests/file_app.sjs

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 var gBasePath = "tests/dom/apps/tests/";
michael@0 2 var gAppTemplatePath = "tests/dom/apps/tests/file_app.template.html";
michael@0 3 var gAppcacheTemplatePath = "tests/dom/apps/tests/file_cached_app.template.appcache";
michael@0 4 var gDefaultIcon = "default_icon";
michael@0 5
michael@0 6 function makeResource(templatePath, version, apptype) {
michael@0 7 let icon = getState('icon') || gDefaultIcon;
michael@0 8 var res = readTemplate(templatePath).replace(/VERSIONTOKEN/g, version)
michael@0 9 .replace(/APPTYPETOKEN/g, apptype)
michael@0 10 .replace(/ICONTOKEN/g, icon);
michael@0 11
michael@0 12 // Hack - This is necessary to make the tests pass, but hbambas says it
michael@0 13 // shouldn't be necessary. Comment it out and watch the tests fail.
michael@0 14 if (templatePath == gAppTemplatePath && apptype == 'cached') {
michael@0 15 res = res.replace('<html>', '<html manifest="file_app.sjs?apptype=cached&getappcache=true">');
michael@0 16 }
michael@0 17
michael@0 18 return res;
michael@0 19 }
michael@0 20
michael@0 21 function handleRequest(request, response) {
michael@0 22 var query = getQuery(request);
michael@0 23
michael@0 24 // If this is a version update, update state and return.
michael@0 25 if ("setVersion" in query) {
michael@0 26 setState('version', query.setVersion);
michael@0 27 response.setHeader("Content-Type", "text/html", false);
michael@0 28 response.setHeader("Access-Control-Allow-Origin", "*", false);
michael@0 29 response.write('OK');
michael@0 30 return;
michael@0 31 }
michael@0 32
michael@0 33 if ("setIcon" in query) {
michael@0 34 let icon = query.setIcon;
michael@0 35 if (icon === 'DEFAULT') {
michael@0 36 icon = null;
michael@0 37 }
michael@0 38
michael@0 39 setState('icon', icon);
michael@0 40
michael@0 41 response.setHeader("Content-Type", "text/html", false);
michael@0 42 response.setHeader("Access-Control-Allow-Origin", "*", false);
michael@0 43 response.write('OK');
michael@0 44 return;
michael@0 45 }
michael@0 46
michael@0 47 // Get the app type.
michael@0 48 var apptype = query.apptype;
michael@0 49 if (apptype != 'hosted' && apptype != 'cached')
michael@0 50 throw "Invalid app type: " + apptype;
michael@0 51
michael@0 52 // Get the version from server state and handle the etag.
michael@0 53 var version = Number(getState('version'));
michael@0 54 var etag = getEtag(request, version);
michael@0 55 dump("Server Etag: " + etag + "\n");
michael@0 56
michael@0 57 if (etagMatches(request, etag)) {
michael@0 58 dump("Etags Match. Sending 304\n");
michael@0 59 response.setStatusLine(request.httpVersion, "304", "Not Modified");
michael@0 60 return;
michael@0 61 }
michael@0 62
michael@0 63 response.setHeader("Etag", etag, false);
michael@0 64 if (request.hasHeader("If-None-Match"))
michael@0 65 dump("Client Etag: " + request.getHeader("If-None-Match") + "\n");
michael@0 66 else
michael@0 67 dump("No Client Etag\n");
michael@0 68
michael@0 69 // Check if we're generating a webapp manifest.
michael@0 70 if ('getmanifest' in query) {
michael@0 71 var template = gBasePath + 'file_' + apptype + '_app.template.webapp';
michael@0 72 response.setHeader("Content-Type", "application/x-web-app-manifest+json", false);
michael@0 73 response.write(makeResource(template, version, apptype));
michael@0 74 return;
michael@0 75 }
michael@0 76
michael@0 77 // If apptype==cached, we might be generating the appcache manifest.
michael@0 78 //
michael@0 79 // NB: Among other reasons, we use the same sjs file here so that the version
michael@0 80 // state is shared.
michael@0 81 if (apptype == 'cached' && 'getappcache' in query) {
michael@0 82 response.setHeader("Content-Type", "text/cache-manifest", false);
michael@0 83 response.write(makeResource(gAppcacheTemplatePath, version, apptype));
michael@0 84 return;
michael@0 85 }
michael@0 86
michael@0 87 // Generate the app.
michael@0 88 response.setHeader("Content-Type", "text/html", false);
michael@0 89 response.write(makeResource(gAppTemplatePath, version, apptype));
michael@0 90 }
michael@0 91
michael@0 92 function getEtag(request, version) {
michael@0 93 return request.queryString.replace(/&/g, '-').replace(/=/g, '-') + '-' + version;
michael@0 94 }
michael@0 95
michael@0 96 function etagMatches(request, etag) {
michael@0 97 return request.hasHeader("If-None-Match") && request.getHeader("If-None-Match") == etag;
michael@0 98 }
michael@0 99
michael@0 100 function getQuery(request) {
michael@0 101 var query = {};
michael@0 102 request.queryString.split('&').forEach(function (val) {
michael@0 103 var [name, value] = val.split('=');
michael@0 104 query[name] = unescape(value);
michael@0 105 });
michael@0 106 return query;
michael@0 107 }
michael@0 108
michael@0 109 // Copy-pasted incantations. There ought to be a better way to synchronously read
michael@0 110 // a file into a string, but I guess we're trying to discourage that.
michael@0 111 function readTemplate(path) {
michael@0 112 var file = Components.classes["@mozilla.org/file/directory_service;1"].
michael@0 113 getService(Components.interfaces.nsIProperties).
michael@0 114 get("CurWorkD", Components.interfaces.nsILocalFile);
michael@0 115 var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
michael@0 116 createInstance(Components.interfaces.nsIFileInputStream);
michael@0 117 var cis = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
michael@0 118 createInstance(Components.interfaces.nsIConverterInputStream);
michael@0 119 var split = path.split("/");
michael@0 120 for(var i = 0; i < split.length; ++i) {
michael@0 121 file.append(split[i]);
michael@0 122 }
michael@0 123 fis.init(file, -1, -1, false);
michael@0 124 cis.init(fis, "UTF-8", 0, 0);
michael@0 125
michael@0 126 var data = "";
michael@0 127 let (str = {}) {
michael@0 128 let read = 0;
michael@0 129 do {
michael@0 130 read = cis.readString(0xffffffff, str); // read as much as we can and put it in str.value
michael@0 131 data += str.value;
michael@0 132 } while (read != 0);
michael@0 133 }
michael@0 134 cis.close();
michael@0 135 return data;
michael@0 136 }

mercurial