uriloader/exthandler/tests/unit_ipc/test_encoding.js

branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
equal deleted inserted replaced
-1:000000000000 0:5cd23de8d917
1
2 const Cc = Components.classes;
3 const Ci = Components.interfaces;
4 const Cu = Components.utils;
5 const Cr = Components.results;
6
7 Cu.import("resource://testing-common/httpd.js");
8 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
9 Cu.import("resource://gre/modules/Services.jsm");
10
11 do_get_profile();
12
13 // Dynamically generates a classID for our component, registers it to mask
14 // the existing component, and stored the masked components classID to be
15 // restored later, when we unregister.
16 function registerTemporaryComponent(comp)
17 {
18 let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
19 if (!comp.prototype.classID) {
20 let uuidgen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
21 comp.prototype.classID = uuidgen.generateUUID();
22 }
23 comp.prototype.maskedClassID = Components.ID(Cc[comp.prototype.contractID].number);
24 if (!comp.prototype.factory)
25 comp.prototype.factory = getFactory(comp);
26 registrar.registerFactory(comp.prototype.classID, "", comp.prototype.contractID, comp.prototype.factory);
27 }
28
29 function unregisterTemporaryComponent(comp)
30 {
31 let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
32 registrar.unregisterFactory(comp.prototype.classID, comp.prototype.factory);
33 registrar.registerFactory(comp.prototype.maskedClassID, "", comp.prototype.contractID, null);
34 }
35
36 let DownloadListener = {
37 init: function () {
38 let obs = Services.obs;
39 obs.addObserver(this, "dl-done", true);
40 },
41
42 observe: function (subject, topic, data) {
43 this.onFinished(subject, topic, data);
44 },
45
46 QueryInterface: function (iid) {
47 if (iid.equals(Ci.nsIObserver) ||
48 iid.equals(Ci.nsISupportsWeakReference) ||
49 iid.equals(Ci.nsISupports))
50 return this;
51
52 throw Cr.NS_ERROR_NO_INTERFACE;
53 }
54 }
55 DownloadListener.init();
56
57 function HelperAppDlg() { }
58 HelperAppDlg.prototype = {
59 QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
60 contractID: "@mozilla.org/helperapplauncherdialog;1",
61 show: function (launcher, ctx, reason, usePrivateUI) {
62 launcher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToFile;
63 launcher.launchWithApplication(null, false);
64 },
65
66 promptForSaveToFile: function (launcher, ctx, defaultFile, suggestedExtension, forcePrompt) { }
67 }
68
69 // Stolen from XPCOMUtils, since this handy function is not public there
70 function getFactory(comp)
71 {
72 return {
73 createInstance: function (outer, iid) {
74 if (outer)
75 throw Cr.NS_ERROR_NO_AGGREGATION;
76 return (new comp()).QueryInterface(iid);
77 }
78 }
79 }
80
81 // Override the download-manager-ui to prevent anyone from trying to open
82 // a window.
83 function DownloadMgrUI() { }
84 DownloadMgrUI.prototype = {
85 QueryInterface: XPCOMUtils.generateQI([Ci.nsIDownloadManagerUI]),
86 contractID: "@mozilla.org/download-manager-ui;1",
87 show: function (ir, aID, reason) { },
88
89 visible: false,
90
91 getAttention: function () { }
92 }
93
94 function AlertsSVC() { }
95 AlertsSVC.prototype = {
96 QueryInterface: XPCOMUtils.generateQI([Ci.nsIAlertsService]),
97 contractID: "@mozilla.org/alerts-service;1",
98 showAlertNotification: function (url, title, text, clickable, cookie, listener, name) { },
99 }
100
101 registerTemporaryComponent(HelperAppDlg);
102 registerTemporaryComponent(DownloadMgrUI);
103 registerTemporaryComponent(AlertsSVC);
104
105 function initChildTestEnv()
106 {
107 sendCommand(' \
108 const Cc = Components.classes; \
109 const Ci = Components.interfaces; \
110 const Cr = Components.results; \
111 function WindowContext() { } \
112 \
113 WindowContext.prototype = { \
114 getInterface: function (iid) { \
115 if (iid.equals(Ci.nsIInterfaceRequestor) || \
116 iid.equals(Ci.nsIURIContentListener) || \
117 iid.equals(Ci.nsILoadGroup) || \
118 iid.equals(Ci.nsIDocumentLoader) || \
119 iid.equals(Ci.nsIDOMWindow)) \
120 return this; \
121 \
122 throw Cr.NS_ERROR_NO_INTERFACE; \
123 }, \
124 \
125 /* nsIURIContentListener */ \
126 onStartURIOpen: function (uri) { }, \
127 isPreferred: function (type, desiredtype) { return false; }, \
128 \
129 /* nsILoadGroup */ \
130 addRequest: function (request, context) { }, \
131 removeRequest: function (request, context, status) { } \
132 }; \
133 \
134 var ioservice = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);\
135 var uriloader = Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader);\
136 ');
137 }
138
139 function testFinisher(endFunc) {
140 let ef = endFunc;
141 return function (file) {
142 ef(file);
143 runNextTest();
144 }
145 }
146
147 function runChildTestSet(set)
148 {
149 DownloadListener.onFinished = testFinisher(set[2]);
150 sendCommand('\
151 let uri = ioservice.newURI("http://localhost:4444' + set[0] + '", null, null);\
152 let channel = ioservice.newChannelFromURI(uri); \
153 uriloader.openURI(channel, Ci.nsIURILoader.IS_CONTENT_PREFERRED, new WindowContext()); \
154 ');
155 }
156
157 var httpserver = null;
158 let currentTest = 0;
159 function runNextTest()
160 {
161 if (currentTest == tests.length) {
162 httpserver.stop(do_test_finished);
163 return;
164 }
165
166 let set = tests[currentTest++];
167 runChildTestSet(set);
168 }
169
170 const responseBody = [0x1f, 0x8b, 0x08, 0x00, 0x16, 0x5a, 0x8a, 0x48, 0x02,
171 0x03, 0x2b, 0x49, 0x2d, 0x2e, 0xe1, 0x02, 0x00, 0xc6,
172 0x35, 0xb9, 0x3b, 0x05, 0x00, 0x00, 0x00];
173
174 /*
175 * First test: a file with Content-Type application/x-gzip and Content-Encoding gzip
176 * should not be decoded in a round-trip
177 */
178 function testResponse1(metadata, response) {
179 response.setHeader("Content-Type", "application/x-gzip", false);
180 response.setHeader("Content-Encoding", "gzip", false);
181 response.setHeader("Content-Disposition", "attachment", false);
182
183 var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
184 bos.setOutputStream(response.bodyOutputStream);
185 bos.writeByteArray(responseBody, responseBody.length);
186 }
187
188 function finishTest1(subject, topic, data) {
189 let file = subject.QueryInterface(Ci.nsIDownload).targetFile;
190 do_check_true(file.path.search("test1.gz") != 0);
191 let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
192 fis.init(file, -1, -1, 0);
193 let bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
194 bis.setInputStream(fis);
195 let str = bis.readByteArray(bis.available());
196 do_check_true(str.length == responseBody.length);
197
198 let cmp = 0;
199 for (i = 0; i < str.length; i++) {
200 cmp += str[i] - responseBody[i];
201 if (cmp != 0) break;
202 }
203 do_check_true(cmp == 0);
204 }
205
206 /*
207 * Second test: a file with Content-Type text/html and Content-Encoding gzip
208 * should not be decoded in a round-trip, if its filename ends in ".gz".
209 * We specify a Content-disposition header to force it to be saved as a file.
210 */
211 function testResponse2(metadata, response) {
212 response.setHeader("Content-Type", "text/html", false);
213 response.setHeader("Content-Encoding", "gzip", false);
214 response.setHeader("Content-Disposition", "attachment", false);
215
216 var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
217 bos.setOutputStream(response.bodyOutputStream);
218 bos.writeByteArray(responseBody, responseBody.length);
219 }
220
221 function finishTest2(subject, topic, data) {
222 let file = subject.QueryInterface(Ci.nsIDownload).targetFile;
223 do_check_true(file.path.search("test2.gz") != 0);
224 let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
225 fis.init(file, -1, -1, 0);
226 let bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
227 bis.setInputStream(fis);
228 let str = bis.readByteArray(bis.available());
229 do_check_true(str.length == responseBody.length);
230
231 let cmp = 0;
232 for (i = 0; i < str.length; i++) {
233 cmp += str[i] - responseBody[i];
234 if (cmp != 0) break;
235 }
236 do_check_true(cmp == 0);
237 }
238
239 function testResponse3(metadata, response) {
240 response.setHeader("Content-Type", "text/html", false);
241 response.setHeader("Content-Encoding", "gzip", false);
242 response.setHeader("Content-Disposition", "attachment", false);
243
244 var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
245 bos.setOutputStream(response.bodyOutputStream);
246 bos.writeByteArray(responseBody, responseBody.length);
247 }
248
249 function finishTest3(subject, topic, data) {
250 let file = subject.QueryInterface(Ci.nsIDownload).targetFile;
251 do_check_true(file.path.search("test3.txt") != 0);
252 let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
253 fis.init(file, -1, -1, 0);
254 let bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
255 bis.setInputStream(fis);
256 let str = bis.readByteArray(bis.available());
257 let decodedBody = [ 116, 101, 115, 116, 10 ]; // 't','e','s','t','\n'
258 do_check_true(str.length == decodedBody.length);
259
260 let cmp = 0;
261 for (i = 0; i < str.length; i++) {
262 cmp += str[i] - decodedBody[i];
263 if (cmp != 0) break;
264 }
265 do_check_true(cmp == 0);
266 }
267
268 let tests = [
269 [ "/test1.gz", testResponse1, finishTest1 ],
270 [ "/test2.gz", testResponse2, finishTest2 ],
271 [ "/test3.txt", testResponse3, finishTest3 ],
272 ];
273
274 function run_test() {
275 // do_load_child_test_harness();
276 httpserver = new HttpServer();
277 httpserver.start(4444);
278 do_test_pending();
279
280 initChildTestEnv();
281
282 for each (set in tests)
283 httpserver.registerPathHandler(set[0], set[1]);
284
285 runNextTest();
286 }

mercurial