michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: // This file tests Bug 593815 - specifically that downloaded files michael@0: // are cleaned up correctly when a download is cancelled michael@0: michael@0: Components.utils.import("resource://gre/modules/Services.jsm"); michael@0: Components.utils.import("resource://gre/modules/NetUtil.jsm"); michael@0: do_load_manifest("test_downloads.manifest"); michael@0: michael@0: let httpserver = null; michael@0: let currentTest = 0; michael@0: michael@0: function WindowContext() { } michael@0: WindowContext.prototype = { michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterfaceRequestor]), michael@0: getInterface: XPCOMUtils.generateQI([Ci.nsIURIContentListener, michael@0: Ci.nsILoadGroup]), michael@0: michael@0: /* nsIURIContentListener */ michael@0: onStartURIOpen: function (uri) { }, michael@0: isPreferred: function (type, desiredtype) { return false; }, michael@0: michael@0: /* nsILoadGroup */ michael@0: addRequest: function (request, context) { }, michael@0: removeRequest: function (request, context, status) { } michael@0: }; michael@0: michael@0: let DownloadListener = { michael@0: set : null, michael@0: init: function () { michael@0: Services.obs.addObserver(this, "dl-start", true); michael@0: Services.obs.addObserver(this, "dl-done", true); michael@0: Services.obs.addObserver(this, "dl-cancel", true); michael@0: Services.obs.addObserver(this, "dl-fail", true); michael@0: }, michael@0: michael@0: // check that relevant cancel operations have been performed michael@0: // currently this just means removing the target file michael@0: onCancel: function(aSubject, aTopic, aData) { michael@0: let dl = aSubject.QueryInterface(Ci.nsIDownload); michael@0: do_check_false(dl.targetFile.exists()); michael@0: runNextTest(); michael@0: }, michael@0: michael@0: observe: function (aSubject, aTopic, aData) { michael@0: switch(aTopic) { michael@0: case "dl-start" : michael@0: // cancel, pause, or resume the download michael@0: // depending on parameters in this.set michael@0: let dl = aSubject.QueryInterface(Ci.nsIDownload); michael@0: michael@0: if (this.set.doPause) { michael@0: downloadUtils.downloadManager.pauseDownload(dl.id); michael@0: } michael@0: michael@0: if (this.set.doResume) { michael@0: downloadUtils.downloadManager.resumeDownload(dl.id); michael@0: } michael@0: michael@0: downloadUtils.downloadManager.cancelDownload(dl.id); michael@0: break; michael@0: case "dl-cancel" : michael@0: this.onCancel(aSubject, aTopic, aData); michael@0: break; michael@0: case "dl-fail" : michael@0: do_throw("Download failed"); michael@0: break; michael@0: case "dl-done" : michael@0: do_throw("Download finished"); michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, michael@0: Ci.nsISupportsWeakReference]) michael@0: } michael@0: michael@0: // loads the uri given in tests[currentTest] michael@0: // finishes tests if there are no more test files listed michael@0: function runNextTest() michael@0: { michael@0: if (currentTest == tests.length) { michael@0: httpserver.stop(do_test_finished); michael@0: return; michael@0: } michael@0: michael@0: let set = DownloadListener.set = tests[currentTest]; michael@0: currentTest++; michael@0: michael@0: let channel = NetUtil.newChannel("http://localhost:" + michael@0: httpserver.identity.primaryPort + michael@0: set.serverPath); michael@0: let uriloader = Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader); michael@0: uriloader.openURI(channel, Ci.nsIURILoader.IS_CONTENT_PREFERRED, michael@0: new WindowContext()); michael@0: } michael@0: michael@0: // sends the responses for the files. sends the same content twice if we resume michael@0: // the download michael@0: function getResponse(aSet) { michael@0: return function(aMetadata, aResponse) { michael@0: aResponse.setHeader("Content-Type", "text/plain", false); michael@0: if (aMetadata.hasHeader("Range")) { michael@0: var matches = aMetadata.getHeader("Range").match(/^\s*bytes=(\d+)?-(\d+)?\s*$/); michael@0: aResponse.setStatusLine(aMetadata.httpVersion, 206, "Partial Content"); michael@0: aResponse.bodyOutputStream.write(aSet.data, aSet.data.length); michael@0: return; michael@0: } michael@0: aResponse.setHeader("Accept-Ranges", "bytes", false); michael@0: aResponse.setHeader("Content-Disposition", "attachment; filename=test.txt;", false); michael@0: aResponse.bodyOutputStream.write(aSet.data, aSet.data.length); michael@0: } michael@0: } michael@0: michael@0: // files to be downloaded. For these tests, files will be cancelled either: michael@0: // 1.) during the download michael@0: // 2.) while they are paused michael@0: // 3.) after they have been resumed michael@0: let tests = [ michael@0: { serverPath: "/test1.html", data: "Test data 1" }, michael@0: { serverPath: "/test2.html", data: "Test data 2", doPause: true }, michael@0: { serverPath: "/test3.html", data: "Test data 3", doPause: true, doResume: true}, michael@0: ]; michael@0: michael@0: function run_test() { michael@0: if (oldDownloadManagerDisabled()) { michael@0: return; michael@0: } michael@0: michael@0: // setup a download listener to run tests during and after the download michael@0: DownloadListener.init(); michael@0: Services.prefs.setBoolPref("browser.download.manager.showWhenStarting", false); michael@0: michael@0: httpserver = new HttpServer(); michael@0: httpserver.start(-1); michael@0: do_test_pending(); michael@0: michael@0: // setup files to be download, each with the same suggested filename michael@0: // from the server, but with different contents michael@0: for(let i = 0; i < tests.length; i++) { michael@0: let set = tests[i]; michael@0: httpserver.registerPathHandler(set.serverPath, getResponse(set)); michael@0: } michael@0: michael@0: runNextTest(); // start downloading the first file michael@0: }