dom/apps/tests/file_app.sjs

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.

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

mercurial