diff options
Diffstat (limited to 'toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs')
-rw-r--r-- | toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs | 103 |
1 files changed, 103 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 0000000000..e2a889c329 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs @@ -0,0 +1,103 @@ +// In an SJS file we need to get NetUtil ourselves, despite +// what eslint might think applies for browser tests. +// eslint-disable-next-line mozilla/no-redeclare-with-import-autofix +let { NetUtil } = ChromeUtils.importESModule( + "resource://gre/modules/NetUtil.sys.mjs" +); + +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 new Error("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"); + + try { + // Doesn't seem to be a sane way to read using IOUtils 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); + }); + + aResponse.processAsync(); + + const dir = Services.dirsvc.get("CurWorkD", Ci.nsIFile).path; + xpiFile = PathUtils.join(dir, ...RELATIVE_PATH.split("/"), params.file); + LOG("Starting slow download of " + xpiFile); + + IOUtils.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); + } +} |