2 SimpleTest.waitForExplicitFinish();
5 function continueTest() {
10 var expectHttp2Results = location.href.includes("http2");
12 var path = "/tests/dom/xhr/tests/";
15 ["file_XHR_pass1.xml", "GET", 200, "OK", "text/xml"],
16 ["file_XHR_pass2.txt", "GET", 200, "OK", "text/plain"],
17 ["file_XHR_pass3.txt", "GET", 200, "OK", "text/plain"],
18 ["data:text/xml,%3Cres%3Ehello%3C/res%3E%0A", "GET", 200, "OK", "text/xml"],
19 ["data:text/plain,hello%20pass%0A", "GET", 200, "OK", "text/plain"],
20 ["data:,foo", "GET", 200, "OK", "text/plain;charset=US-ASCII", "foo"],
21 ["data:text/plain;base64,Zm9v", "GET", 200, "OK", "text/plain", "foo"],
22 ["data:text/plain,foo#bar", "GET", 200, "OK", "text/plain", "foo"],
23 ["data:text/plain,foo%23bar", "GET", 200, "OK", "text/plain", "foo#bar"],
26 var blob = new Blob(["foo"], { type: "text/plain" });
27 var blobURL = URL.createObjectURL(blob);
29 passFiles.push([blobURL, "GET", 200, "OK", "text/plain", "foo"]);
32 ["//example.com" + path + "file_XHR_pass1.xml", "GET"],
33 ["ftp://localhost" + path + "file_XHR_pass1.xml", "GET"],
34 ["file_XHR_fail1.txt", "GET"],
37 for (i = 0; i < passFiles.length; ++i) {
38 // Function to give our hacked is() a scope
40 function is(actual, expected, message) {
41 oldIs(actual, expected, message + " for " + passFiles[i][0]);
43 xhr = new XMLHttpRequest();
44 is(xhr.getResponseHeader("Content-Type"), null, "should be null");
45 is(xhr.getAllResponseHeaders(), "", "should be empty string");
46 is(xhr.responseType, "", "wrong initial responseType");
47 xhr.open(passFiles[i][1], passFiles[i][0], false);
49 is(xhr.status, passFiles[i][2], "wrong status");
51 // over HTTP2, no status text is received for network requests (but
52 // data/blob URLs default to "200 OK" responses)
53 let expectedStatusText = passFiles[i][3];
56 !passFiles[i][0].startsWith("data:") &&
57 !passFiles[i][0].startsWith("blob:")
59 expectedStatusText = "";
61 is(xhr.statusText, expectedStatusText, "wrong statusText");
64 xhr.getResponseHeader("Content-Type"),
68 var headers = xhr.getAllResponseHeaders();
70 /(?:^|\n)Content-Type:\s*([^\r\n]*)\r\n/i.test(headers) &&
71 RegExp.$1 === passFiles[i][4],
72 "wrong response headers"
74 if (xhr.responseXML) {
76 new XMLSerializer().serializeToString(
77 xhr.responseXML.documentElement
79 passFiles[i][5] || "<res>hello</res>",
84 passFiles[i][5] || "<res>hello</res>\n",
90 passFiles[i][5] || "hello pass\n",
93 is(xhr.response, passFiles[i][5] || "hello pass\n", "wrong response");
98 URL.revokeObjectURL(blobURL);
100 for (i = 0; i < failFiles.length; ++i) {
101 xhr = new XMLHttpRequest();
102 let didthrow = false;
104 xhr.open(failFiles[i][1], failFiles[i][0], false);
110 is(xhr.status, 301, "wrong status");
111 is(xhr.responseText, "redirect file\n", "wrong response");
113 ok(1, "should have thrown or given incorrect result");
117 function checkResponseTextAccessThrows(xhr) {
118 let didthrow = false;
124 ok(didthrow, "should have thrown when accessing responseText");
126 function checkResponseXMLAccessThrows(xhr) {
127 let didthrow = false;
133 ok(didthrow, "should have thrown when accessing responseXML");
135 function checkSetResponseType(xhr, type) {
136 let didthrow = false;
138 xhr.responseType = type;
142 is(xhr.responseType, type, "responseType should be " + type);
143 ok(!didthrow, "should not have thrown when setting responseType");
145 function checkSetResponseTypeThrows(xhr, type) {
146 let didthrow = false;
148 xhr.responseType = type;
152 ok(didthrow, "should have thrown when setting responseType");
154 function checkOpenThrows(xhr, method, url, async) {
155 let didthrow = false;
157 xhr.open(method, url, async);
161 ok(didthrow, "should have thrown when open is called");
164 // test if setting responseType before calling open() works
165 xhr = new XMLHttpRequest();
166 checkSetResponseType(xhr, "");
167 checkSetResponseType(xhr, "text");
168 checkSetResponseType(xhr, "document");
169 checkSetResponseType(xhr, "arraybuffer");
170 checkSetResponseType(xhr, "blob");
171 checkSetResponseType(xhr, "json");
172 checkOpenThrows(xhr, "GET", "file_XHR_pass2.txt", false);
174 // test response (sync, responseType is not changeable)
175 xhr = new XMLHttpRequest();
176 xhr.open("GET", "file_XHR_pass2.txt", false);
177 checkSetResponseTypeThrows(xhr, "");
178 checkSetResponseTypeThrows(xhr, "text");
179 checkSetResponseTypeThrows(xhr, "document");
180 checkSetResponseTypeThrows(xhr, "arraybuffer");
181 checkSetResponseTypeThrows(xhr, "blob");
182 checkSetResponseTypeThrows(xhr, "json");
184 checkSetResponseTypeThrows(xhr, "document");
185 is(xhr.status, 200, "wrong status");
186 is(xhr.response, "hello pass\n", "wrong response");
188 // test response (responseType='document')
189 xhr = new XMLHttpRequest();
190 xhr.open("GET", "file_XHR_pass1.xml");
191 xhr.responseType = "document";
192 xhr.onloadend = continueTest;
195 checkSetResponseTypeThrows(xhr, "document");
196 is(xhr.status, 200, "wrong status");
197 checkResponseTextAccessThrows(xhr);
199 new XMLSerializer().serializeToString(xhr.response.documentElement),
204 // test response (responseType='text')
205 xhr = new XMLHttpRequest();
206 xhr.open("GET", "file_XHR_pass2.txt");
207 xhr.responseType = "text";
208 xhr.onloadend = continueTest;
211 is(xhr.status, 200, "wrong status");
212 checkResponseXMLAccessThrows(xhr);
213 is(xhr.response, "hello pass\n", "wrong response");
215 // test response (responseType='arraybuffer')
216 function arraybuffer_equals_to(ab, s) {
217 is(ab.byteLength, s.length, "wrong arraybuffer byteLength");
219 var u8v = new Uint8Array(ab);
220 is(String.fromCharCode.apply(String, u8v), s, "wrong values");
223 // with a simple text file
224 xhr = new XMLHttpRequest();
225 xhr.open("GET", "file_XHR_pass2.txt");
226 xhr.responseType = "arraybuffer";
227 xhr.onloadend = continueTest;
230 is(xhr.status, 200, "wrong status");
231 checkResponseTextAccessThrows(xhr);
232 checkResponseXMLAccessThrows(xhr);
233 var ab = xhr.response;
234 ok(ab != null, "should have a non-null arraybuffer");
235 arraybuffer_equals_to(ab, "hello pass\n");
237 // test reusing the same XHR (Bug 680816)
238 xhr.open("GET", "file_XHR_binary1.bin");
239 xhr.responseType = "arraybuffer";
240 xhr.onloadend = continueTest;
243 is(xhr.status, 200, "wrong status");
244 var ab2 = xhr.response;
245 ok(ab2 != null, "should have a non-null arraybuffer");
246 ok(ab2 != ab, "arraybuffer on XHR reuse should be distinct");
247 arraybuffer_equals_to(ab, "hello pass\n");
248 arraybuffer_equals_to(ab2, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb");
250 // with a binary file
251 xhr = new XMLHttpRequest();
252 xhr.open("GET", "file_XHR_binary1.bin");
253 xhr.responseType = "arraybuffer";
254 xhr.onloadend = continueTest;
257 is(xhr.status, 200, "wrong status");
258 checkResponseTextAccessThrows(xhr);
259 checkResponseXMLAccessThrows(xhr);
261 ok(ab != null, "should have a non-null arraybuffer");
262 arraybuffer_equals_to(ab, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb");
263 is(xhr.response, xhr.response, "returns the same ArrayBuffer");
265 // test response (responseType='json')
266 var xhr = new XMLHttpRequest();
267 xhr.open("POST", "responseIdentical.sjs");
268 xhr.responseType = "json";
269 var jsonObjStr = JSON.stringify({ title: "aBook", author: "john" });
270 xhr.onloadend = continueTest;
271 xhr.send(jsonObjStr);
273 is(xhr.status, 200, "wrong status");
274 checkResponseTextAccessThrows(xhr);
275 checkResponseXMLAccessThrows(xhr);
276 is(JSON.stringify(xhr.response), jsonObjStr, "correct result");
277 is(xhr.response, xhr.response, "returning the same object on each access");
280 xhr = new XMLHttpRequest();
281 xhr.open("POST", "responseIdentical.sjs");
282 xhr.responseType = "json";
283 xhr.onloadend = continueTest;
286 is(xhr.status, 200, "wrong status");
287 checkResponseTextAccessThrows(xhr);
288 checkResponseXMLAccessThrows(xhr);
289 is(xhr.response, null, "Bad JSON should result in null response.");
293 "Bad JSON should result in null response even 2nd time."
296 // Test status/statusText in all readyStates
297 xhr = new XMLHttpRequest();
298 function checkXHRStatus() {
299 if (xhr.readyState == xhr.UNSENT || xhr.readyState == xhr.OPENED) {
300 is(xhr.status, 0, "should be 0 before getting data");
301 is(xhr.statusText, "", "should be empty before getting data");
303 is(xhr.status, 200, "should be 200 when we have data");
304 if (expectHttp2Results) {
305 is(xhr.statusText, "", "should be '' when over HTTP2");
307 is(xhr.statusText, "OK", "should be OK when we have data");
312 xhr.open("GET", "file_XHR_binary1.bin");
314 xhr.responseType = "arraybuffer";
316 xhr.onreadystatechange = continueTest;
317 while (xhr.readyState != 4) {
323 // test response (responseType='blob')
324 // with a simple text file
325 xhr = new XMLHttpRequest();
326 xhr.open("GET", "file_XHR_pass2.txt");
327 xhr.responseType = "blob";
328 xhr.onloadend = continueTest;
331 is(xhr.status, 200, "wrong status");
332 checkResponseTextAccessThrows(xhr);
333 checkResponseXMLAccessThrows(xhr);
334 var b = xhr.response;
335 ok(b, "should have a non-null blob");
336 ok(b instanceof Blob, "should be a Blob");
337 ok(!(b instanceof File), "should not be a File");
338 is(b.size, "hello pass\n".length, "wrong blob size");
340 var fr = new FileReader();
341 fr.onload = continueTest;
342 fr.readAsBinaryString(b);
344 is(fr.result, "hello pass\n", "wrong values");
346 // with a binary file
347 xhr = new XMLHttpRequest();
348 xhr.open("GET", "file_XHR_binary1.bin", true);
350 xhr.onreadystatechange = continueTest;
351 while (xhr.readyState != 2) {
355 is(xhr.status, 200, "wrong status");
356 xhr.responseType = "blob";
358 while (xhr.readyState != 4) {
362 xhr.onreadystatechange = null;
365 ok(b != null, "should have a non-null blob");
366 is(b.size, 12, "wrong blob size");
368 fr = new FileReader();
369 fr.readAsBinaryString(b);
370 xhr = null; // kill the XHR object
373 fr.onload = continueTest;
377 "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb",
381 // with a larger binary file
382 xhr = new XMLHttpRequest();
383 xhr.open("GET", "file_XHR_binary2.bin", true);
384 xhr.responseType = "blob";
386 xhr.onreadystatechange = continueTest;
388 while (xhr.readyState != 4) {
392 xhr.onreadystatechange = null;
395 ok(b != null, "should have a non-null blob");
396 is(b.size, 65536, "wrong blob size");
398 fr = new FileReader();
399 fr.readAsArrayBuffer(b);
400 fr.onload = continueTest;
401 xhr = null; // kill the XHR object
406 var u8 = new Uint8Array(fr.result);
407 for (var i = 0; i < 65536; i++) {
408 if (u8[i] !== (i & 255)) {
412 is(i, 65536, "wrong value at offset " + i);
414 var client = new XMLHttpRequest();
415 client.open("GET", "file_XHR_pass1.xml", true);
417 client.onreadystatechange = function () {
418 if (client.readyState == 4) {
420 is(client.responseXML, null, "responseXML should be null.");
421 is(client.responseText, "", "responseText should be empty string.");
422 is(client.response, "", "response should be empty string.");
423 is(client.status, 0, "status should be 0.");
424 is(client.statusText, "", "statusText should be empty string.");
426 client.getAllResponseHeaders(),
428 "getAllResponseHeaders() should return empty string."
431 ok(false, "Shouldn't throw! [" + ex + "]");