1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/uriloader/exthandler/tests/unit_ipc/test_encoding.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,286 @@ 1.4 + 1.5 +const Cc = Components.classes; 1.6 +const Ci = Components.interfaces; 1.7 +const Cu = Components.utils; 1.8 +const Cr = Components.results; 1.9 + 1.10 +Cu.import("resource://testing-common/httpd.js"); 1.11 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.12 +Cu.import("resource://gre/modules/Services.jsm"); 1.13 + 1.14 +do_get_profile(); 1.15 + 1.16 +// Dynamically generates a classID for our component, registers it to mask 1.17 +// the existing component, and stored the masked components classID to be 1.18 +// restored later, when we unregister. 1.19 +function registerTemporaryComponent(comp) 1.20 +{ 1.21 + let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); 1.22 + if (!comp.prototype.classID) { 1.23 + let uuidgen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator); 1.24 + comp.prototype.classID = uuidgen.generateUUID(); 1.25 + } 1.26 + comp.prototype.maskedClassID = Components.ID(Cc[comp.prototype.contractID].number); 1.27 + if (!comp.prototype.factory) 1.28 + comp.prototype.factory = getFactory(comp); 1.29 + registrar.registerFactory(comp.prototype.classID, "", comp.prototype.contractID, comp.prototype.factory); 1.30 +} 1.31 + 1.32 +function unregisterTemporaryComponent(comp) 1.33 +{ 1.34 + let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); 1.35 + registrar.unregisterFactory(comp.prototype.classID, comp.prototype.factory); 1.36 + registrar.registerFactory(comp.prototype.maskedClassID, "", comp.prototype.contractID, null); 1.37 +} 1.38 + 1.39 +let DownloadListener = { 1.40 + init: function () { 1.41 + let obs = Services.obs; 1.42 + obs.addObserver(this, "dl-done", true); 1.43 + }, 1.44 + 1.45 + observe: function (subject, topic, data) { 1.46 + this.onFinished(subject, topic, data); 1.47 + }, 1.48 + 1.49 + QueryInterface: function (iid) { 1.50 + if (iid.equals(Ci.nsIObserver) || 1.51 + iid.equals(Ci.nsISupportsWeakReference) || 1.52 + iid.equals(Ci.nsISupports)) 1.53 + return this; 1.54 + 1.55 + throw Cr.NS_ERROR_NO_INTERFACE; 1.56 + } 1.57 +} 1.58 +DownloadListener.init(); 1.59 + 1.60 +function HelperAppDlg() { } 1.61 +HelperAppDlg.prototype = { 1.62 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]), 1.63 + contractID: "@mozilla.org/helperapplauncherdialog;1", 1.64 + show: function (launcher, ctx, reason, usePrivateUI) { 1.65 + launcher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToFile; 1.66 + launcher.launchWithApplication(null, false); 1.67 + }, 1.68 + 1.69 + promptForSaveToFile: function (launcher, ctx, defaultFile, suggestedExtension, forcePrompt) { } 1.70 +} 1.71 + 1.72 +// Stolen from XPCOMUtils, since this handy function is not public there 1.73 +function getFactory(comp) 1.74 +{ 1.75 + return { 1.76 + createInstance: function (outer, iid) { 1.77 + if (outer) 1.78 + throw Cr.NS_ERROR_NO_AGGREGATION; 1.79 + return (new comp()).QueryInterface(iid); 1.80 + } 1.81 + } 1.82 +} 1.83 + 1.84 +// Override the download-manager-ui to prevent anyone from trying to open 1.85 +// a window. 1.86 +function DownloadMgrUI() { } 1.87 +DownloadMgrUI.prototype = { 1.88 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIDownloadManagerUI]), 1.89 + contractID: "@mozilla.org/download-manager-ui;1", 1.90 + show: function (ir, aID, reason) { }, 1.91 + 1.92 + visible: false, 1.93 + 1.94 + getAttention: function () { } 1.95 +} 1.96 + 1.97 +function AlertsSVC() { } 1.98 +AlertsSVC.prototype = { 1.99 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIAlertsService]), 1.100 + contractID: "@mozilla.org/alerts-service;1", 1.101 + showAlertNotification: function (url, title, text, clickable, cookie, listener, name) { }, 1.102 +} 1.103 + 1.104 +registerTemporaryComponent(HelperAppDlg); 1.105 +registerTemporaryComponent(DownloadMgrUI); 1.106 +registerTemporaryComponent(AlertsSVC); 1.107 + 1.108 +function initChildTestEnv() 1.109 +{ 1.110 + sendCommand(' \ 1.111 + const Cc = Components.classes; \ 1.112 + const Ci = Components.interfaces; \ 1.113 + const Cr = Components.results; \ 1.114 + function WindowContext() { } \ 1.115 + \ 1.116 + WindowContext.prototype = { \ 1.117 + getInterface: function (iid) { \ 1.118 + if (iid.equals(Ci.nsIInterfaceRequestor) || \ 1.119 + iid.equals(Ci.nsIURIContentListener) || \ 1.120 + iid.equals(Ci.nsILoadGroup) || \ 1.121 + iid.equals(Ci.nsIDocumentLoader) || \ 1.122 + iid.equals(Ci.nsIDOMWindow)) \ 1.123 + return this; \ 1.124 + \ 1.125 + throw Cr.NS_ERROR_NO_INTERFACE; \ 1.126 + }, \ 1.127 + \ 1.128 + /* nsIURIContentListener */ \ 1.129 + onStartURIOpen: function (uri) { }, \ 1.130 + isPreferred: function (type, desiredtype) { return false; }, \ 1.131 + \ 1.132 + /* nsILoadGroup */ \ 1.133 + addRequest: function (request, context) { }, \ 1.134 + removeRequest: function (request, context, status) { } \ 1.135 + }; \ 1.136 + \ 1.137 + var ioservice = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);\ 1.138 + var uriloader = Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader);\ 1.139 + '); 1.140 +} 1.141 + 1.142 +function testFinisher(endFunc) { 1.143 + let ef = endFunc; 1.144 + return function (file) { 1.145 + ef(file); 1.146 + runNextTest(); 1.147 + } 1.148 +} 1.149 + 1.150 +function runChildTestSet(set) 1.151 +{ 1.152 + DownloadListener.onFinished = testFinisher(set[2]); 1.153 + sendCommand('\ 1.154 + let uri = ioservice.newURI("http://localhost:4444' + set[0] + '", null, null);\ 1.155 + let channel = ioservice.newChannelFromURI(uri); \ 1.156 + uriloader.openURI(channel, Ci.nsIURILoader.IS_CONTENT_PREFERRED, new WindowContext()); \ 1.157 + '); 1.158 +} 1.159 + 1.160 +var httpserver = null; 1.161 +let currentTest = 0; 1.162 +function runNextTest() 1.163 +{ 1.164 + if (currentTest == tests.length) { 1.165 + httpserver.stop(do_test_finished); 1.166 + return; 1.167 + } 1.168 + 1.169 + let set = tests[currentTest++]; 1.170 + runChildTestSet(set); 1.171 +} 1.172 + 1.173 +const responseBody = [0x1f, 0x8b, 0x08, 0x00, 0x16, 0x5a, 0x8a, 0x48, 0x02, 1.174 + 0x03, 0x2b, 0x49, 0x2d, 0x2e, 0xe1, 0x02, 0x00, 0xc6, 1.175 + 0x35, 0xb9, 0x3b, 0x05, 0x00, 0x00, 0x00]; 1.176 + 1.177 +/* 1.178 + * First test: a file with Content-Type application/x-gzip and Content-Encoding gzip 1.179 + * should not be decoded in a round-trip 1.180 + */ 1.181 +function testResponse1(metadata, response) { 1.182 + response.setHeader("Content-Type", "application/x-gzip", false); 1.183 + response.setHeader("Content-Encoding", "gzip", false); 1.184 + response.setHeader("Content-Disposition", "attachment", false); 1.185 + 1.186 + var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream); 1.187 + bos.setOutputStream(response.bodyOutputStream); 1.188 + bos.writeByteArray(responseBody, responseBody.length); 1.189 +} 1.190 + 1.191 +function finishTest1(subject, topic, data) { 1.192 + let file = subject.QueryInterface(Ci.nsIDownload).targetFile; 1.193 + do_check_true(file.path.search("test1.gz") != 0); 1.194 + let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); 1.195 + fis.init(file, -1, -1, 0); 1.196 + let bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); 1.197 + bis.setInputStream(fis); 1.198 + let str = bis.readByteArray(bis.available()); 1.199 + do_check_true(str.length == responseBody.length); 1.200 + 1.201 + let cmp = 0; 1.202 + for (i = 0; i < str.length; i++) { 1.203 + cmp += str[i] - responseBody[i]; 1.204 + if (cmp != 0) break; 1.205 + } 1.206 + do_check_true(cmp == 0); 1.207 +} 1.208 + 1.209 +/* 1.210 + * Second test: a file with Content-Type text/html and Content-Encoding gzip 1.211 + * should not be decoded in a round-trip, if its filename ends in ".gz". 1.212 + * We specify a Content-disposition header to force it to be saved as a file. 1.213 + */ 1.214 +function testResponse2(metadata, response) { 1.215 + response.setHeader("Content-Type", "text/html", false); 1.216 + response.setHeader("Content-Encoding", "gzip", false); 1.217 + response.setHeader("Content-Disposition", "attachment", false); 1.218 + 1.219 + var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream); 1.220 + bos.setOutputStream(response.bodyOutputStream); 1.221 + bos.writeByteArray(responseBody, responseBody.length); 1.222 +} 1.223 + 1.224 +function finishTest2(subject, topic, data) { 1.225 + let file = subject.QueryInterface(Ci.nsIDownload).targetFile; 1.226 + do_check_true(file.path.search("test2.gz") != 0); 1.227 + let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); 1.228 + fis.init(file, -1, -1, 0); 1.229 + let bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); 1.230 + bis.setInputStream(fis); 1.231 + let str = bis.readByteArray(bis.available()); 1.232 + do_check_true(str.length == responseBody.length); 1.233 + 1.234 + let cmp = 0; 1.235 + for (i = 0; i < str.length; i++) { 1.236 + cmp += str[i] - responseBody[i]; 1.237 + if (cmp != 0) break; 1.238 + } 1.239 + do_check_true(cmp == 0); 1.240 +} 1.241 + 1.242 +function testResponse3(metadata, response) { 1.243 + response.setHeader("Content-Type", "text/html", false); 1.244 + response.setHeader("Content-Encoding", "gzip", false); 1.245 + response.setHeader("Content-Disposition", "attachment", false); 1.246 + 1.247 + var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream); 1.248 + bos.setOutputStream(response.bodyOutputStream); 1.249 + bos.writeByteArray(responseBody, responseBody.length); 1.250 +} 1.251 + 1.252 +function finishTest3(subject, topic, data) { 1.253 + let file = subject.QueryInterface(Ci.nsIDownload).targetFile; 1.254 + do_check_true(file.path.search("test3.txt") != 0); 1.255 + let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); 1.256 + fis.init(file, -1, -1, 0); 1.257 + let bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); 1.258 + bis.setInputStream(fis); 1.259 + let str = bis.readByteArray(bis.available()); 1.260 + let decodedBody = [ 116, 101, 115, 116, 10 ]; // 't','e','s','t','\n' 1.261 + do_check_true(str.length == decodedBody.length); 1.262 + 1.263 + let cmp = 0; 1.264 + for (i = 0; i < str.length; i++) { 1.265 + cmp += str[i] - decodedBody[i]; 1.266 + if (cmp != 0) break; 1.267 + } 1.268 + do_check_true(cmp == 0); 1.269 +} 1.270 + 1.271 +let tests = [ 1.272 + [ "/test1.gz", testResponse1, finishTest1 ], 1.273 + [ "/test2.gz", testResponse2, finishTest2 ], 1.274 + [ "/test3.txt", testResponse3, finishTest3 ], 1.275 +]; 1.276 + 1.277 +function run_test() { 1.278 +// do_load_child_test_harness(); 1.279 + httpserver = new HttpServer(); 1.280 + httpserver.start(4444); 1.281 + do_test_pending(); 1.282 + 1.283 + initChildTestEnv(); 1.284 + 1.285 + for each (set in tests) 1.286 + httpserver.registerPathHandler(set[0], set[1]); 1.287 + 1.288 + runNextTest(); 1.289 +}