summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs')
-rw-r--r--toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs101
1 files changed, 101 insertions, 0 deletions
diff --git a/toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs b/toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs
new file mode 100644
index 000000000..5f767a8f4
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs
@@ -0,0 +1,101 @@
+const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/osfile.jsm");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
+const RELATIVE_PATH = "browser/toolkit/mozapps/extensions/test/xpinstall"
+const NOTIFICATION_TOPIC = "slowinstall-complete";
+
+/**
+ * Helper function to create a JS object representing the url parameters from
+ * the request's queryString.
+ *
+ * @param aQueryString
+ * The request's query string.
+ * @return A JS object representing the url parameters from the request's
+ * queryString.
+ */
+function parseQueryString(aQueryString) {
+ var paramArray = aQueryString.split("&");
+ var regex = /^([^=]+)=(.*)$/;
+ var params = {};
+ for (var i = 0, sz = paramArray.length; i < sz; i++) {
+ var match = regex.exec(paramArray[i]);
+ if (!match)
+ throw "Bad parameter in queryString! '" + paramArray[i] + "'";
+ params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
+ }
+
+ return params;
+}
+
+function handleRequest(aRequest, aResponse) {
+ let id = +getState("ID");
+ setState("ID", "" + (id + 1));
+
+ function LOG(str) {
+ dump("slowinstall.sjs[" + id + "]: " + str + "\n");
+ }
+
+ aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
+
+ var params = { };
+ if (aRequest.queryString)
+ params = parseQueryString(aRequest.queryString);
+
+ if (params.file) {
+ let xpiFile = "";
+
+ function complete_download() {
+ LOG("Completing download");
+ downloadPaused = false;
+
+ try {
+ // Doesn't seem to be a sane way to read using OS.File and write to an
+ // nsIOutputStream so here we are.
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ file.initWithPath(xpiFile);
+ let stream = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ stream.init(file, -1, -1, stream.DEFER_OPEN + stream.CLOSE_ON_EOF);
+
+ NetUtil.asyncCopy(stream, aResponse.bodyOutputStream, () => {
+ LOG("Download complete");
+ aResponse.finish();
+ });
+ }
+ catch (e) {
+ LOG("Exception " + e);
+ }
+ }
+
+ let waitForComplete = new Promise(resolve => {
+ function complete() {
+ Services.obs.removeObserver(complete, NOTIFICATION_TOPIC);
+ resolve();
+ }
+
+ Services.obs.addObserver(complete, NOTIFICATION_TOPIC, false);
+ });
+
+ aResponse.processAsync();
+
+ OS.File.getCurrentDirectory().then(dir => {
+ xpiFile = OS.Path.join(dir, ...RELATIVE_PATH.split("/"), params.file);
+ LOG("Starting slow download of " + xpiFile);
+
+ OS.File.stat(xpiFile).then(info => {
+ aResponse.setHeader("Content-Type", "binary/octet-stream");
+ aResponse.setHeader("Content-Length", info.size.toString());
+
+ LOG("Download paused");
+ waitForComplete.then(complete_download);
+ });
+ });
+ }
+ else if (params.continue) {
+ dump("slowinstall.sjs: Received signal to complete all current downloads.\n");
+ Services.obs.notifyObservers(null, NOTIFICATION_TOPIC, null);
+ }
+}