diff options
Diffstat (limited to 'dom/xhr/tests')
106 files changed, 5560 insertions, 0 deletions
diff --git a/dom/xhr/tests/browser.ini b/dom/xhr/tests/browser.ini new file mode 100644 index 000000000..6bf9a3fc8 --- /dev/null +++ b/dom/xhr/tests/browser.ini @@ -0,0 +1,5 @@ +[DEFAULT] +support-files = + browser_xhr_onchange_leak.html +[browser_blobFromFile.js] +[browser_xhr_onchange_leak.js]
\ No newline at end of file diff --git a/dom/xhr/tests/browser_xhr_onchange_leak.html b/dom/xhr/tests/browser_xhr_onchange_leak.html new file mode 100644 index 000000000..56eb45533 --- /dev/null +++ b/dom/xhr/tests/browser_xhr_onchange_leak.html @@ -0,0 +1,25 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test page for https://bugzilla.mozilla.org/show_bug.cgi?id=1336811 +--> +<head> + <meta charset="utf-8"> + <title>Test page for Bug 1336811</title> +</head> +<body onload="onload();"> +<p><span id="samplepage">sample page</span></p> +<script type="application/javascript"> + function onload() { + var request = new XMLHttpRequest; + request.open("GET", "about:blank"); + request.onreadystatechange = function() { + request.foo = request; + } + request.foo = request; + request.send(); + request.foo = request; + } +</script> +</body> +</html> diff --git a/dom/xhr/tests/browser_xhr_onchange_leak.js b/dom/xhr/tests/browser_xhr_onchange_leak.js new file mode 100644 index 000000000..f4dbb7e3e --- /dev/null +++ b/dom/xhr/tests/browser_xhr_onchange_leak.js @@ -0,0 +1,23 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +// Bug 1336811 - An XHR that has a .onreadystatechange waiting should +// not leak forever once the tab is closed. CC optimizations need to be +// turned off once it is closed. + +add_task(function* test() { + const url = "http://mochi.test:8888/browser/dom/xhr/tests/browser_xhr_onchange_leak.html"; + let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url); + let browser = gBrowser.selectedBrowser; + let done = yield ContentTask.spawn(browser,{}, function*(browser){ + let doc = content.document; + let promise = ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", true); + content.location = "about:home"; + yield promise; + return true; + }); + is(done, true, "need to check something"); + yield BrowserTestUtils.removeTab(newTab); +}); diff --git a/dom/xhr/tests/common_temporaryFileBlob.js b/dom/xhr/tests/common_temporaryFileBlob.js new file mode 100644 index 000000000..81a66238d --- /dev/null +++ b/dom/xhr/tests/common_temporaryFileBlob.js @@ -0,0 +1,100 @@ +var data = new Array(256).join("1234567890ABCDEF"); + +function createXHR() { + var xhr = new XMLHttpRequest(); + xhr.open("POST", "temporaryFileBlob.sjs"); + xhr.responseType = 'blob'; + xhr.send({toString: function() { return data; }}); + return xhr; +} + +function test_simple() { + info("Simple test"); + + var xhr = createXHR(); + + xhr.onloadend = function() { + ok(xhr.response instanceof Blob, "We have a blob!"); + is(xhr.response.size, data.length, "Data length matches"); + + var fr = new FileReader(); + fr.readAsText(xhr.response); + fr.onload = function() { + is(fr.result, data, "Data content matches"); + next(); + } + } +} + +function test_abort() { + info("Aborting during onloading"); + + var xhr = createXHR(); + + xhr.onprogress = function() { + xhr.abort(); + } + + xhr.onloadend = function() { + ok(!xhr.response, "We should not have a Blob!"); + next(); + } +} + +function test_reuse() { + info("Reuse test"); + + var xhr = createXHR(); + + var count = 0; + xhr.onloadend = function() { + ok(xhr.response instanceof Blob, "We have a blob!"); + is(xhr.response.size, data.length, "Data length matches"); + + var fr = new FileReader(); + fr.readAsText(xhr.response); + fr.onload = function() { + is(fr.result, data, "Data content matches"); + if (++count > 2) { + next(); + return; + } + + xhr.open("POST", "temporaryFileBlob.sjs"); + xhr.responseType = 'blob'; + xhr.send({toString: function() { return data; }}); + } + } +} + +function test_worker_generic(test) { + var w = new Worker('worker_temporaryFileBlob.js'); + w.onmessage = function(e) { + if (e.data.type == 'info') { + info(e.data.msg); + } else if (e.data.type == 'check') { + ok(e.data.what, e.data.msg); + } else if (e.data.type == 'finish') { + next(); + } else { + ok(false, 'Something wrong happened'); + } + } + + w.postMessage(test); +} + +function test_worker() { + info("XHR in workers"); + test_worker_generic('simple'); +} + +function test_worker_abort() { + info("XHR in workers"); + test_worker_generic('abort'); +} + +function test_worker_reuse() { + info("XHR in workers"); + test_worker_generic('reuse'); +} diff --git a/dom/xhr/tests/echo.sjs b/dom/xhr/tests/echo.sjs new file mode 100644 index 000000000..6e3242c9f --- /dev/null +++ b/dom/xhr/tests/echo.sjs @@ -0,0 +1,21 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function handleRequest(request, response) +{ + response.setHeader("Content-Type", "text/plain"); + if (request.method == "GET") { + response.write(request.queryString); + return; + } + + var bodyStream = new BinaryInputStream(request.bodyInputStream); + var body = ""; + var bodyAvail; + while ((bodyAvail = bodyStream.available()) > 0) + body += String.fromCharCode.apply(null, bodyStream.readByteArray(bodyAvail)); + + response.write(body); +} diff --git a/dom/xhr/tests/empty.html b/dom/xhr/tests/empty.html new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/dom/xhr/tests/empty.html diff --git a/dom/xhr/tests/file_XHRDocURI.html b/dom/xhr/tests/file_XHRDocURI.html new file mode 100644 index 000000000..8dbbb0549 --- /dev/null +++ b/dom/xhr/tests/file_XHRDocURI.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> + <head> + <title>XMLHttpRequest return document URIs</title> + </head> + <body> + <div id="data">data</div> + </body> +</html> diff --git a/dom/xhr/tests/file_XHRDocURI.html^headers^ b/dom/xhr/tests/file_XHRDocURI.html^headers^ new file mode 100644 index 000000000..ddfd8c0a9 --- /dev/null +++ b/dom/xhr/tests/file_XHRDocURI.html^headers^ @@ -0,0 +1,3 @@ +HTTP 200 OK +Access-Control-Allow-Origin: * +Content-Type: text/html diff --git a/dom/xhr/tests/file_XHRDocURI.sjs b/dom/xhr/tests/file_XHRDocURI.sjs new file mode 100644 index 000000000..275b1e96e --- /dev/null +++ b/dom/xhr/tests/file_XHRDocURI.sjs @@ -0,0 +1,13 @@ +function handleRequest(aRequest, aResponse) +{ + var url = aRequest.queryString.match(/\burl=([^#&]*)/); + if (!url) { + aResponse.setStatusLine(aRequest.httpVersion, 404, "Not Found"); + return; + } + + url = decodeURIComponent(url[1]); + aResponse.setStatusLine(aRequest.httpVersion, 302, "Found"); + aResponse.setHeader("Cache-Control", "no-cache", false); + aResponse.setHeader("Location", url, false); +} diff --git a/dom/xhr/tests/file_XHRDocURI.text b/dom/xhr/tests/file_XHRDocURI.text new file mode 100644 index 000000000..c1dead8d7 --- /dev/null +++ b/dom/xhr/tests/file_XHRDocURI.text @@ -0,0 +1 @@ +<res>data</res> diff --git a/dom/xhr/tests/file_XHRDocURI.text^headers^ b/dom/xhr/tests/file_XHRDocURI.text^headers^ new file mode 100644 index 000000000..b2fe7cdeb --- /dev/null +++ b/dom/xhr/tests/file_XHRDocURI.text^headers^ @@ -0,0 +1,3 @@ +HTTP 200 OK +Access-Control-Allow-Origin: * +Content-Type: text/plain diff --git a/dom/xhr/tests/file_XHRDocURI.xml b/dom/xhr/tests/file_XHRDocURI.xml new file mode 100644 index 000000000..c1a9a5256 --- /dev/null +++ b/dom/xhr/tests/file_XHRDocURI.xml @@ -0,0 +1 @@ +<res xml:base="http://www.example.com/">data</res> diff --git a/dom/xhr/tests/file_XHRDocURI.xml^headers^ b/dom/xhr/tests/file_XHRDocURI.xml^headers^ new file mode 100644 index 000000000..f47804337 --- /dev/null +++ b/dom/xhr/tests/file_XHRDocURI.xml^headers^ @@ -0,0 +1,3 @@ +HTTP 200 OK +Access-Control-Allow-Origin: * +Content-Type: application/xml diff --git a/dom/xhr/tests/file_XHRResponseURL.js b/dom/xhr/tests/file_XHRResponseURL.js new file mode 100644 index 000000000..7c48201b2 --- /dev/null +++ b/dom/xhr/tests/file_XHRResponseURL.js @@ -0,0 +1,303 @@ +"use strict"; + +// utility functions for worker/window communication + +function isInWorker() { + try { + return !(self instanceof Window); + } catch (e) { + return true; + } +} + +function message(aData) { + if (isInWorker()) { + self.postMessage(aData); + } else { + self.postMessage(aData, "*"); + } +} +message.ping = 0; +message.pong = 0; + +function is(aActual, aExpected, aMessage) { + var obj = { + type: "is", + actual: aActual, + expected: aExpected, + message: aMessage + }; + ++message.ping; + message(obj); +} + +function ok(aBool, aMessage) { + var obj = { + type: "ok", + bool: aBool, + message: aMessage + }; + ++message.ping; + message(obj); +} + +function info(aMessage) { + var obj = { + type: "info", + message: aMessage + }; + ++message.ping; + message(obj); +} + +function request(aURL) { + return new Promise(function (aResolve, aReject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", aURL); + xhr.addEventListener("load", function () { + xhr.succeeded = true; + aResolve(xhr); + }); + xhr.addEventListener("error", function () { + xhr.succeeded = false; + aResolve(xhr); + }); + xhr.send(); + }); +} + +function createSequentialRequest(aParameters, aTest) { + var sequence = aParameters.reduce(function (aPromise, aParam) { + return aPromise.then(function () { + return request(aParam.requestURL); + }).then(function (aXHR) { + return aTest(aXHR, aParam); + }); + }, Promise.resolve()); + + return sequence; +} + +function testSuccessResponse() { + var blob = new Blob(["data"], {type: "text/plain"}); + var blobURL = URL.createObjectURL(blob); + + var parameters = [ + // tests that start with same-origin request + { + message: "request to same-origin without redirect", + requestURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text", + responseURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text" + }, + { + message: "request to same-origin redirect to same-origin URL", + requestURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text", + responseURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text" + }, + { + message: "request to same-origin redirects several times and finally go to same-origin URL", + requestURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=" + encodeURIComponent("http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text"), + responseURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text" + }, + { + message: "request to same-origin redirect to cross-origin URL", + requestURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text", + responseURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text", + }, + { + message: "request to same-origin redirects several times and finally go to cross-origin URL", + requestURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=" + encodeURIComponent("http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text"), + responseURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text", + }, + + // tests that start with cross-origin request + { + message: "request to cross-origin without redirect", + requestURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text", + responseURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text" + }, + { + message: "request to cross-origin redirect back to same-origin URL", + requestURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text", + responseURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text" + }, + { + message: "request to cross-origin redirect to the same cross-origin URL", + requestURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text", + responseURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text", + }, + { + message: "request to cross-origin redirect to another cross-origin URL", + requestURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://example.org/tests/dom/xhr/tests/file_XHRResponseURL.text", + responseURL: "http://example.org/tests/dom/xhr/tests/file_XHRResponseURL.text", + }, + { + message: "request to cross-origin redirects several times and finally go to same-origin URL", + requestURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=" + encodeURIComponent("http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text"), + responseURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text", + }, + { + message: "request to cross-origin redirects several times and finally go to the same cross-origin URL", + requestURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=" + encodeURIComponent("http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text"), + responseURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.text", + }, + { + message: "request to cross-origin redirects several times and finally go to another cross-origin URL", + requestURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=" + encodeURIComponent("http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://example.org/tests/dom/xhr/tests/file_XHRResponseURL.text"), + responseURL: "http://example.org/tests/dom/xhr/tests/file_XHRResponseURL.text", + }, + { + message: "request to cross-origin redirects to another cross-origin and finally go to the other cross-origin URL", + requestURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=" + encodeURIComponent("http://example.org/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://test1.example.com/tests/dom/xhr/tests/file_XHRResponseURL.text"), + responseURL: "http://test1.example.com/tests/dom/xhr/tests/file_XHRResponseURL.text", + }, + { + message: "request URL has fragment", + requestURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text#fragment", + responseURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text" + }, + + // tests for non-http(s) URL + { + message: "request to data: URL", + requestURL: "data:text/plain,data", + responseURL: "data:text/plain,data" + }, + { + message: "request to blob: URL", + requestURL: blobURL, + responseURL: blobURL + } + ]; + + var sequence = createSequentialRequest(parameters, function (aXHR, aParam) { + ok(aXHR.succeeded, "assert request succeeded"); + is(aXHR.responseURL, aParam.responseURL, aParam.message); + }); + + sequence.then(function () { + URL.revokeObjectURL(blobURL); + }); + + return sequence; +} + +function testFailedResponse() { + info("test not to leak responseURL for denied cross-origin request"); + var parameters = [ + { + message: "should be empty for denied cross-origin request without redirect", + requestURL: "http://example.com/tests/dom/xhr/tests/file_XHRResponseURL_nocors.text" + }, + { + message: "should be empty for denied cross-origin request with redirect", + requestURL: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRResponseURL_nocors.text" + } + ]; + + var sequence = createSequentialRequest(parameters, function (aXHR, aParam) { + ok(!aXHR.succeeded, "assert request failed"); + is(aXHR.responseURL, "" , aParam.message); + }); + + return sequence; +} + +function testNotToLeakResponseURLWhileDoingRedirects() { + info("test not to leak responeseURL while doing redirects"); + + if (isInWorker()) { + return testNotToLeakResponseURLWhileDoingRedirectsInWorker(); + } else { + return testNotToLeakResponseURLWhileDoingRedirectsInWindow(); + } +} + +function testNotToLeakResponseURLWhileDoingRedirectsInWindow() { + var xhr = new XMLHttpRequest(); + var requestObserver = { + observe: function (aSubject, aTopic, aData) { + is(xhr.readyState, XMLHttpRequest.OPENED, "assert for XHR state"); + is(xhr.responseURL, "", + "responseURL should return empty string before HEADERS_RECEIVED"); + } + }; + SpecialPowers.addObserver(requestObserver, "specialpowers-http-notify-request", false); + + return new Promise(function (aResolve, aReject) { + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text"); + xhr.addEventListener("load", function () { + SpecialPowers.removeObserver(requestObserver, "specialpowers-http-notify-request"); + aResolve(); + }); + xhr.addEventListener("error", function () { + ok(false, "unexpected request falilure"); + SpecialPowers.removeObserver(requestObserver, "specialpowers-http-notify-request"); + aResolve(); + }); + xhr.send(); + }); +} + +function testNotToLeakResponseURLWhileDoingRedirectsInWorker() { + var xhr = new XMLHttpRequest(); + var testRedirect = function (e) { + if (e.data === "request" && xhr.readyState === XMLHttpRequest.OPENED) { + is(xhr.responseURL, "", + "responseURL should return empty string before HEADERS_RECEIVED"); + } + }; + + return new Promise(function (aResolve, aReject) { + self.addEventListener("message", testRedirect); + message({type: "redirect_test", status: "start"}); + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.sjs?url=http://mochi.test:8888/tests/dom/xhr/tests/file_XHRResponseURL.text"); + xhr.addEventListener("load", function () { + self.removeEventListener("message", testRedirect); + message({type: "redirect_test", status: "end"}); + aResolve(); + }); + xhr.addEventListener("error", function (e) { + ok(false, "unexpected request falilure"); + self.removeEventListener("message", testRedirect); + message({type: "redirect_test", status: "end"}); + aResolve(); + }); + xhr.send(); + }); +} + +function waitForAllMessagesProcessed() { + return new Promise(function (aResolve, aReject) { + var id = setInterval(function () { + if (message.ping === message.pong) { + clearInterval(id); + aResolve(); + } + }, 100); + }); +} + + +self.addEventListener("message", function (aEvent) { + if (aEvent.data === "start") { + ok("responseURL" in (new XMLHttpRequest()), + "XMLHttpRequest should have responseURL attribute"); + is((new XMLHttpRequest()).responseURL, "", + "responseURL should be empty string if response's url is null"); + + var promise = testSuccessResponse(); + promise.then(function () { + return testFailedResponse(); + }).then(function () { + return testNotToLeakResponseURLWhileDoingRedirects(); + }).then(function () { + return waitForAllMessagesProcessed(); + }).then(function () { + message("done"); + }); + } + if (aEvent.data === "pong") { + ++message.pong; + } +}); diff --git a/dom/xhr/tests/file_XHRResponseURL.sjs b/dom/xhr/tests/file_XHRResponseURL.sjs new file mode 100644 index 000000000..5ac0a346c --- /dev/null +++ b/dom/xhr/tests/file_XHRResponseURL.sjs @@ -0,0 +1,14 @@ +function handleRequest(aRequest, aResponse) +{ + var url = aRequest.queryString.match(/\burl=([^#&]*)/); + if (!url) { + aResponse.setStatusLine(aRequest.httpVersion, 404, "Not Found"); + return; + } + url = decodeURIComponent(url[1]); + + aResponse.setStatusLine(aRequest.httpVersion, 302, "Found"); + aResponse.setHeader("Access-Control-Allow-Origin", "*", false); + aResponse.setHeader("Cache-Control", "no-cache", false); + aResponse.setHeader("Location", url, false); +} diff --git a/dom/xhr/tests/file_XHRResponseURL.text b/dom/xhr/tests/file_XHRResponseURL.text new file mode 100644 index 000000000..1269488f7 --- /dev/null +++ b/dom/xhr/tests/file_XHRResponseURL.text @@ -0,0 +1 @@ +data diff --git a/dom/xhr/tests/file_XHRResponseURL.text^headers^ b/dom/xhr/tests/file_XHRResponseURL.text^headers^ new file mode 100644 index 000000000..b2fe7cdeb --- /dev/null +++ b/dom/xhr/tests/file_XHRResponseURL.text^headers^ @@ -0,0 +1,3 @@ +HTTP 200 OK +Access-Control-Allow-Origin: * +Content-Type: text/plain diff --git a/dom/xhr/tests/file_XHRResponseURL_nocors.text b/dom/xhr/tests/file_XHRResponseURL_nocors.text new file mode 100644 index 000000000..1269488f7 --- /dev/null +++ b/dom/xhr/tests/file_XHRResponseURL_nocors.text @@ -0,0 +1 @@ +data diff --git a/dom/xhr/tests/file_XHRSendData.sjs b/dom/xhr/tests/file_XHRSendData.sjs new file mode 100644 index 000000000..0ccbe8a45 --- /dev/null +++ b/dom/xhr/tests/file_XHRSendData.sjs @@ -0,0 +1,30 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function handleRequest(request, response) +{ + if (request.hasHeader("Content-Type")) + response.setHeader("Result-Content-Type", + request.getHeader("Content-Type")); + + response.setHeader("Content-Type", "text/plain; charset=ISO-8859-1"); + + var body = new BinaryInputStream(request.bodyInputStream); + var avail; + var bytes = []; + while ((avail = body.available()) > 0) + Array.prototype.push.apply(bytes, body.readByteArray(avail)); + + var data = String.fromCharCode.apply(null, bytes); + response.setHeader("Result-Content-Length", "" + data.length); + if (data.indexOf("TEST_REDIRECT_STR") >= 0) { + var newURL = "http://" + data.split("&url=")[1]; + response.setStatusLine(null, 307, "redirect"); + response.setHeader("Location", newURL, false); + } + else { + response.write(data); + } +} diff --git a/dom/xhr/tests/file_XHRSendData_doc.xml b/dom/xhr/tests/file_XHRSendData_doc.xml new file mode 100644 index 000000000..2e385258c --- /dev/null +++ b/dom/xhr/tests/file_XHRSendData_doc.xml @@ -0,0 +1,2 @@ +<!-- comment --> +<out>hi</out> diff --git a/dom/xhr/tests/file_XHRSendData_doc.xml^headers^ b/dom/xhr/tests/file_XHRSendData_doc.xml^headers^ new file mode 100644 index 000000000..b0f1ebfbf --- /dev/null +++ b/dom/xhr/tests/file_XHRSendData_doc.xml^headers^ @@ -0,0 +1 @@ +Content-Type: application/xml; charset=ISO-8859-1 diff --git a/dom/xhr/tests/file_XHR_anon.sjs b/dom/xhr/tests/file_XHR_anon.sjs new file mode 100644 index 000000000..755c4cdf3 --- /dev/null +++ b/dom/xhr/tests/file_XHR_anon.sjs @@ -0,0 +1,24 @@ +function handleRequest(request, response) { + let invalidHeaders = ["Cookie"]; + let headers = {}; + + if (request.queryString == "expectAuth=true") { + if (request.hasHeader("Authorization")) { + headers["authorization"] = request.getHeader("Authorization"); + } else { + response.setStatusLine(null, 401, "Authentication required"); + response.setHeader("WWW-Authenticate", "basic realm=\"testrealm\"", true); + } + } else { + invalidHeaders.push("Authorization"); + } + + for (let header of invalidHeaders) { + if (request.hasHeader(header)) { + response.setStatusLine(null, 500, "Server Error"); + headers[header.toLowerCase()] = request.getHeader(header); + } + } + + response.write(JSON.stringify(headers)); +} diff --git a/dom/xhr/tests/file_XHR_binary1.bin b/dom/xhr/tests/file_XHR_binary1.bin Binary files differnew file mode 100644 index 000000000..39e527bfc --- /dev/null +++ b/dom/xhr/tests/file_XHR_binary1.bin diff --git a/dom/xhr/tests/file_XHR_binary1.bin^headers^ b/dom/xhr/tests/file_XHR_binary1.bin^headers^ new file mode 100644 index 000000000..8e8c8d859 --- /dev/null +++ b/dom/xhr/tests/file_XHR_binary1.bin^headers^ @@ -0,0 +1 @@ +Content-Type: application/binary diff --git a/dom/xhr/tests/file_XHR_binary2.bin b/dom/xhr/tests/file_XHR_binary2.bin Binary files differnew file mode 100644 index 000000000..9f442b092 --- /dev/null +++ b/dom/xhr/tests/file_XHR_binary2.bin diff --git a/dom/xhr/tests/file_XHR_fail1.txt b/dom/xhr/tests/file_XHR_fail1.txt new file mode 100644 index 000000000..462209d8d --- /dev/null +++ b/dom/xhr/tests/file_XHR_fail1.txt @@ -0,0 +1 @@ +redirect file diff --git a/dom/xhr/tests/file_XHR_fail1.txt^headers^ b/dom/xhr/tests/file_XHR_fail1.txt^headers^ new file mode 100644 index 000000000..41c235932 --- /dev/null +++ b/dom/xhr/tests/file_XHR_fail1.txt^headers^ @@ -0,0 +1,2 @@ +HTTP 301 Moved Permanently +Location: http://example.com/tests/dom/xhr/tests/file_XHR_pass2.txt diff --git a/dom/xhr/tests/file_XHR_fail1b.txt b/dom/xhr/tests/file_XHR_fail1b.txt new file mode 100644 index 000000000..8944657af --- /dev/null +++ b/dom/xhr/tests/file_XHR_fail1b.txt @@ -0,0 +1 @@ +hello pass
diff --git a/dom/xhr/tests/file_XHR_header.sjs b/dom/xhr/tests/file_XHR_header.sjs new file mode 100644 index 000000000..937e90a02 --- /dev/null +++ b/dom/xhr/tests/file_XHR_header.sjs @@ -0,0 +1,6 @@ +// SJS file for getAllResponseRequests vs getResponseRequest
+function handleRequest(request, response)
+{
+ response.setHeader("X-Custom-Header-Bytes", "…", false);
+ response.write("42");
+}
diff --git a/dom/xhr/tests/file_XHR_pass1.xml b/dom/xhr/tests/file_XHR_pass1.xml new file mode 100644 index 000000000..06826d6c6 --- /dev/null +++ b/dom/xhr/tests/file_XHR_pass1.xml @@ -0,0 +1 @@ +<res>hello</res> diff --git a/dom/xhr/tests/file_XHR_pass2.txt b/dom/xhr/tests/file_XHR_pass2.txt new file mode 100644 index 000000000..0d7f879f9 --- /dev/null +++ b/dom/xhr/tests/file_XHR_pass2.txt @@ -0,0 +1 @@ +hello pass diff --git a/dom/xhr/tests/file_XHR_pass3.txt b/dom/xhr/tests/file_XHR_pass3.txt new file mode 100644 index 000000000..462209d8d --- /dev/null +++ b/dom/xhr/tests/file_XHR_pass3.txt @@ -0,0 +1 @@ +redirect file diff --git a/dom/xhr/tests/file_XHR_pass3.txt^headers^ b/dom/xhr/tests/file_XHR_pass3.txt^headers^ new file mode 100644 index 000000000..fb5056c38 --- /dev/null +++ b/dom/xhr/tests/file_XHR_pass3.txt^headers^ @@ -0,0 +1,2 @@ +HTTP 301 Moved Permanently +Location: file_XHR_pass2.txt diff --git a/dom/xhr/tests/file_XHR_system_redirect.html b/dom/xhr/tests/file_XHR_system_redirect.html new file mode 100644 index 000000000..8267b01d0 --- /dev/null +++ b/dom/xhr/tests/file_XHR_system_redirect.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<html> +<body> +</body> +</html>
\ No newline at end of file diff --git a/dom/xhr/tests/file_XHR_system_redirect.html^headers^ b/dom/xhr/tests/file_XHR_system_redirect.html^headers^ new file mode 100644 index 000000000..cefb165b0 --- /dev/null +++ b/dom/xhr/tests/file_XHR_system_redirect.html^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Found +Location: file:///etc/passwd diff --git a/dom/xhr/tests/file_XHR_timeout.sjs b/dom/xhr/tests/file_XHR_timeout.sjs new file mode 100644 index 000000000..b349d122e --- /dev/null +++ b/dom/xhr/tests/file_XHR_timeout.sjs @@ -0,0 +1,15 @@ +var timer = null; + +function handleRequest(request, response) +{ + response.processAsync(); + timer = Components.classes["@mozilla.org/timer;1"] + .createInstance(Components.interfaces.nsITimer); + timer.initWithCallback(function() + { + response.setStatusLine(null, 200, "OK"); + response.setHeader("Content-Type", "text/plain", false); + response.write("hello"); + response.finish(); + }, 3000 /* milliseconds */, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} diff --git a/dom/xhr/tests/file_html_in_xhr.html b/dom/xhr/tests/file_html_in_xhr.html new file mode 100644 index 000000000..d77aeb440 --- /dev/null +++ b/dom/xhr/tests/file_html_in_xhr.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html><!-- Þ --> +<meta charset="Windows-1251"> +<script> +document.documentElement.setAttribute("data-fail", "FAIL"); +</script> +<script src="file_html_in_xhr.sjs"></script> +<script src="file_html_in_xhr.sjs" defer></script> +<script src="file_html_in_xhr.sjs" async></script> +<link type="stylesheet" href="file_html_in_xhr.sjs"> +<body onload='document.documentElement.setAttribute("data-fail", "FAIL");'> +<img src="file_html_in_xhr.sjs"> +<iframe src="file_html_in_xhr.sjs"></iframe> +<video poster="file_html_in_xhr.sjs" src="file_html_in_xhr.sjs"></video> +<object data="file_html_in_xhr.sjs"></object> +<noscript><div></div></noscript> diff --git a/dom/xhr/tests/file_html_in_xhr.sjs b/dom/xhr/tests/file_html_in_xhr.sjs new file mode 100644 index 000000000..8f4075ae7 --- /dev/null +++ b/dom/xhr/tests/file_html_in_xhr.sjs @@ -0,0 +1,15 @@ +function handleRequest(request, response) +{ + response.setHeader("Content-Type", "text/javascript", false); + if (request.queryString.indexOf("report") != -1) { + if (getState("loaded") == "loaded") { + response.write("ok(false, 'This script was not supposed to get fetched.'); continueAfterReport();"); + } else { + response.write("ok(true, 'This script was not supposed to get fetched.'); continueAfterReport();"); + } + } else { + setState("loaded", "loaded"); + response.write('document.documentElement.setAttribute("data-fail", "FAIL");'); + } +} + diff --git a/dom/xhr/tests/file_html_in_xhr2.html b/dom/xhr/tests/file_html_in_xhr2.html new file mode 100644 index 000000000..046052c75 --- /dev/null +++ b/dom/xhr/tests/file_html_in_xhr2.html @@ -0,0 +1 @@ +<meta charset="windows-1251">Þ diff --git a/dom/xhr/tests/file_html_in_xhr3.html b/dom/xhr/tests/file_html_in_xhr3.html new file mode 100644 index 000000000..ff43ca409 --- /dev/null +++ b/dom/xhr/tests/file_html_in_xhr3.html @@ -0,0 +1 @@ +SUCCESS diff --git a/dom/xhr/tests/file_sync_xhr_document_write_with_iframe.html b/dom/xhr/tests/file_sync_xhr_document_write_with_iframe.html new file mode 100644 index 000000000..060389427 --- /dev/null +++ b/dom/xhr/tests/file_sync_xhr_document_write_with_iframe.html @@ -0,0 +1,21 @@ +<!DOCTYPE HTML> +<body> +<script> +function syncXHR() { + let xhr = new XMLHttpRequest(); + xhr.open("GET", window.location, false); + xhr.send(null); +} + +addEventListener('load', evt => { + syncXHR(); + document.open(); + document.write( + '<body>' + + '<iframe src="about:blank"></iframe>' + + '<script>window.opener.postMessage("DONE", "*");</' + 'script>' + + '</body>'); + document.close(); +}, { once: true }); +</script> +</body> diff --git a/dom/xhr/tests/iframe_sync_xhr_unload.html b/dom/xhr/tests/iframe_sync_xhr_unload.html new file mode 100644 index 000000000..d58b1994c --- /dev/null +++ b/dom/xhr/tests/iframe_sync_xhr_unload.html @@ -0,0 +1,18 @@ +<!DOCTYPE HTML> +<html> +<body> + <script type="application/javascript"> + +function o() { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "sync_xhr_unload.sjs", false); + try { xhr.send(); } catch(e) {} +} + +window.addEventListener("beforeunload", o, false); +window.addEventListener("unload", o, false) + + </script> +</body> +</html> + diff --git a/dom/xhr/tests/mochitest.ini b/dom/xhr/tests/mochitest.ini new file mode 100644 index 000000000..35ba1e3db --- /dev/null +++ b/dom/xhr/tests/mochitest.ini @@ -0,0 +1,115 @@ +[DEFAULT] +support-files = + echo.sjs + temporaryFileBlob.sjs + file_html_in_xhr.html + file_html_in_xhr.sjs + file_html_in_xhr2.html + file_html_in_xhr3.html + file_XHRDocURI.text + file_XHRDocURI.text^headers^ + file_XHRDocURI.xml + file_XHRDocURI.xml^headers^ + file_XHRDocURI.html + file_XHRDocURI.html^headers^ + file_XHRDocURI.sjs + file_XHRResponseURL.js + file_XHRResponseURL.sjs + file_XHRResponseURL.text + file_XHRResponseURL.text^headers^ + file_XHRResponseURL_nocors.text + file_XHRSendData.sjs + file_XHRSendData_doc.xml + file_XHRSendData_doc.xml^headers^ + file_XHR_anon.sjs + file_XHR_binary1.bin + file_XHR_binary1.bin^headers^ + file_XHR_binary2.bin + file_XHR_fail1.txt + file_XHR_fail1.txt^headers^ + file_XHR_header.sjs + file_XHR_pass1.xml + file_XHR_pass2.txt + file_XHR_pass3.txt + file_XHR_pass3.txt^headers^ + file_XHR_system_redirect.html + file_XHR_system_redirect.html^headers^ + file_XHR_timeout.sjs + progressserver.sjs + worker_terminateSyncXHR_frame.html + terminateSyncXHR_worker.js + worker_testXHR.txt + xhr_worker.js + xhr2_worker.js + xhrAbort_worker.js + test_worker_xhr_parameters.js + test_worker_xhr_system.js + worker_xhr_cors_redirect.js + worker_xhr_cors_redirect.sjs + worker_xhr_headers_server.sjs + worker_xhr_headers_worker.js + worker_file_getcookie.sjs + xhr_implicit_cancel_worker.js + relativeLoad_import.js + relativeLoad_worker.js + relativeLoad_worker2.js + responseIdentical.sjs + subdir/relativeLoad_sub_worker.js + subdir/relativeLoad_sub_worker2.js + subdir/relativeLoad_sub_import.js + common_temporaryFileBlob.js + worker_temporaryFileBlob.js + worker_bug1300552.js + sync_xhr_unload.sjs + iframe_sync_xhr_unload.html + empty.html + file_sync_xhr_document_write_with_iframe.html + +[test_bug1300552.html] +[test_html_in_xhr.html] +[test_relativeLoad.html] +skip-if = buildapp == 'b2g' # b2g(Failed to load script: relativeLoad_import.js) b2g-debug(Failed to load script: relativeLoad_import.js) b2g-desktop(Failed to load script: relativeLoad_import.js) +[test_sync_xhr_timer.xhtml] +skip-if = toolkit == 'android' +[test_sync_xhr_unload.html] +[test_temporaryFileBlob.html] +[test_worker_terminateSyncXHR.html] +skip-if = buildapp == 'b2g' +[test_worker_xhr.html] +[test_worker_xhr2.html] +[test_worker_xhr_3rdparty.html] +[test_worker_xhr_cors_redirect.html] +[test_worker_xhr_headers.html] +[test_worker_xhr_implicit_cancel.html] +[test_worker_xhr_parameters.html] +skip-if = buildapp == 'b2g' +[test_worker_xhr_responseURL.html] +[test_worker_xhr_system.html] +[test_worker_xhr_timeout.html] +[test_worker_xhrAbort.html] +skip-if = (os == "win") || (os == "mac") || toolkit == 'android' #bug 798220 +[test_XHR.html] +[test_xhr_abort_after_load.html] +skip-if = toolkit == 'android' +[test_XHR_anon.html] +[test_xhr_forbidden_headers.html] +[test_XHR_header.html] +[test_XHR_onuploadprogress.html] +[test_xhr_overridemimetype_throws_on_invalid_state.html] +skip-if = buildapp == 'b2g' # Requires webgl support +[test_XHR_parameters.html] +skip-if = buildapp == 'b2g' # b2g(86 total, 4 failing - testing mozAnon - got false, expected true) b2g-debug(86 total, 4 failing - testing mozAnon - got false, expected true) b2g-desktop(86 total, 4 failing - testing mozAnon - got false, expected true) +[test_xhr_progressevents.html] +skip-if = toolkit == 'android' +[test_xhr_send.html] +[test_xhr_send_readystate.html] +[test_XHR_system.html] +skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(12 total, 2 failing - .mozSystem == true - got false, expected true + ) b2g-desktop(12 total, 2 failing - .mozSystem == true - got false, expected true + ) +[test_XHR_timeout.html] +skip-if = buildapp == 'b2g' || (android_version == '18' && debug) # b2g(flaky on B2G, bug 960743) b2g-debug(flaky on B2G, bug 960743) b2g-desktop(flaky on B2G, bug 960743) +support-files = test_XHR_timeout.js +[test_xhr_withCredentials.html] +[test_XHRDocURI.html] +[test_XHRResponseURL.html] +[test_XHRSendData.html] +[test_sync_xhr_document_write_with_iframe.html] diff --git a/dom/xhr/tests/progressserver.sjs b/dom/xhr/tests/progressserver.sjs new file mode 100644 index 000000000..945f79557 --- /dev/null +++ b/dom/xhr/tests/progressserver.sjs @@ -0,0 +1,52 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function setReq(req) { + setObjectState("dom/xhr/tests/progressserver", req); +} + +function getReq() { + var req; + getObjectState("dom/xhr/tests/progressserver", function(v) { + req = v; + }); + return req; +} + +function handleRequest(request, response) +{ + var pairs = request.queryString.split('&'); + var command = pairs.shift(); + dump("received '" + command + "' command\n"); + + var bodyStream = new BinaryInputStream(request.bodyInputStream); + var body = ""; + var bodyAvail; + while ((bodyAvail = bodyStream.available()) > 0) + body += String.fromCharCode.apply(null, bodyStream.readByteArray(bodyAvail)); + + if (command == "open") { + response.processAsync(); + setReq(response); + + response.setHeader("Cache-Control", "no-cache", false); + pairs.forEach(function (val) { + var [name, value] = val.split('='); + response.setHeader(name, unescape(value), false); + }); + response.write(body); + return; + } + + if (command == "send") { + getReq().write(body); + } + else if (command == "close") { + getReq().finish(); + setReq(null); + } + response.setHeader("Content-Type", "text/plain"); + response.write("ok"); +} diff --git a/dom/xhr/tests/relativeLoad_import.js b/dom/xhr/tests/relativeLoad_import.js new file mode 100644 index 000000000..114d1883c --- /dev/null +++ b/dom/xhr/tests/relativeLoad_import.js @@ -0,0 +1,5 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +const workerURL = "relativeLoad_worker.js"; diff --git a/dom/xhr/tests/relativeLoad_worker.js b/dom/xhr/tests/relativeLoad_worker.js new file mode 100644 index 000000000..42959db30 --- /dev/null +++ b/dom/xhr/tests/relativeLoad_worker.js @@ -0,0 +1,27 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +const importURL = "relativeLoad_import.js"; + +onmessage = function(event) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "worker_testXHR.txt", false); + xhr.send(null); + if (xhr.status != 200 || + xhr.responseText != "A noisy noise annoys an oyster.") { + throw "Couldn't get xhr text from where we wanted it!"; + } + + importScripts(importURL); + var worker = new Worker("relativeLoad_worker2.js"); + worker.onerror = function(event) { + throw event.message; + }; + worker.onmessage = function(event) { + if (event.data != workerURL) { + throw "Bad data!"; + } + postMessage(workerURL); + } +}; diff --git a/dom/xhr/tests/relativeLoad_worker2.js b/dom/xhr/tests/relativeLoad_worker2.js new file mode 100644 index 000000000..e9fbdf903 --- /dev/null +++ b/dom/xhr/tests/relativeLoad_worker2.js @@ -0,0 +1,9 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +const importURL = "relativeLoad_import.js"; + +importScripts(importURL); + +postMessage(workerURL); diff --git a/dom/xhr/tests/responseIdentical.sjs b/dom/xhr/tests/responseIdentical.sjs new file mode 100644 index 000000000..f1986819a --- /dev/null +++ b/dom/xhr/tests/responseIdentical.sjs @@ -0,0 +1,17 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +// Simply sending back the same data that is received +function handleRequest(request, response) +{ + var body = ""; + var bodyStream = new BinaryInputStream(request.bodyInputStream); + var bytes = [], avail = 0; + while ((avail = bodyStream.available()) > 0) + body += String.fromCharCode.apply(String, bodyStream.readByteArray(avail)); + + response.setHeader("Content-Type", "application/octet-stream", false); + response.write(body); +} diff --git a/dom/xhr/tests/subdir/relativeLoad_sub_import.js b/dom/xhr/tests/subdir/relativeLoad_sub_import.js new file mode 100644 index 000000000..cac2a6f04 --- /dev/null +++ b/dom/xhr/tests/subdir/relativeLoad_sub_import.js @@ -0,0 +1,5 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +const workerSubURL = "subdir/relativeLoad_sub_worker.js"; diff --git a/dom/xhr/tests/subdir/relativeLoad_sub_worker.js b/dom/xhr/tests/subdir/relativeLoad_sub_worker.js new file mode 100644 index 000000000..f725cfb61 --- /dev/null +++ b/dom/xhr/tests/subdir/relativeLoad_sub_worker.js @@ -0,0 +1,26 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +const importSubURL = "relativeLoad_sub_import.js"; + +onmessage = function(event) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "testXHR.txt", false); + xhr.send(null); + if (xhr.status != 404) { + throw "Loaded an xhr from the wrong location!"; + } + + importScripts(importSubURL); + var worker = new Worker("relativeLoad_sub_worker2.js"); + worker.onerror = function(event) { + throw event.data; + }; + worker.onmessage = function(event) { + if (event.data != workerSubURL) { + throw "Bad data!"; + } + postMessage(workerSubURL); + }; +}; diff --git a/dom/xhr/tests/subdir/relativeLoad_sub_worker2.js b/dom/xhr/tests/subdir/relativeLoad_sub_worker2.js new file mode 100644 index 000000000..f47a29ee6 --- /dev/null +++ b/dom/xhr/tests/subdir/relativeLoad_sub_worker2.js @@ -0,0 +1,9 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +const importSubURL = "relativeLoad_sub_import.js"; + +importScripts(importSubURL); + +postMessage(workerSubURL); diff --git a/dom/xhr/tests/sync_xhr_unload.sjs b/dom/xhr/tests/sync_xhr_unload.sjs new file mode 100644 index 000000000..4185056e3 --- /dev/null +++ b/dom/xhr/tests/sync_xhr_unload.sjs @@ -0,0 +1,15 @@ +var timer = null; + +function handleRequest(request, response) +{ + response.processAsync(); + timer = Components.classes["@mozilla.org/timer;1"] + .createInstance(Components.interfaces.nsITimer); + timer.initWithCallback(function() + { + response.setStatusLine(null, 200, "OK"); + response.setHeader("Content-Type", "text/plain", false); + response.write("hello"); + response.finish(); + }, 30000 /* milliseconds */, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} diff --git a/dom/xhr/tests/temporaryFileBlob.sjs b/dom/xhr/tests/temporaryFileBlob.sjs new file mode 100644 index 000000000..ff3410c78 --- /dev/null +++ b/dom/xhr/tests/temporaryFileBlob.sjs @@ -0,0 +1,33 @@ +const CC = Components.Constructor; + +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); +const BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1", + "nsIBinaryOutputStream", + "setOutputStream"); +const Timer = CC("@mozilla.org/timer;1", + "nsITimer", + "initWithCallback"); + +function handleRequest(request, response) { + var bodyStream = new BinaryInputStream(request.bodyInputStream); + var bodyBytes = []; + while ((bodyAvail = bodyStream.available()) > 0) + Array.prototype.push.apply(bodyBytes, bodyStream.readByteArray(bodyAvail)); + + var bos = new BinaryOutputStream(response.bodyOutputStream); + + response.processAsync(); + + var part = bodyBytes.splice(0, 256); + bos.writeByteArray(part, part.length); + + response.timer1 = new Timer(function(timer) { + bos.writeByteArray(bodyBytes, bodyBytes.length); + }, 1000, Components.interfaces.nsITimer.TYPE_ONE_SHOT); + + response.timer2 = new Timer(function(timer) { + response.finish(); + }, 2000, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} diff --git a/dom/xhr/tests/terminateSyncXHR_worker.js b/dom/xhr/tests/terminateSyncXHR_worker.js new file mode 100644 index 000000000..c86baeb42 --- /dev/null +++ b/dom/xhr/tests/terminateSyncXHR_worker.js @@ -0,0 +1,19 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +onmessage = function(event) { + throw "No messages should reach me!"; +} + +var xhr = new XMLHttpRequest(); +xhr.open("GET", "worker_testXHR.txt", false); +xhr.addEventListener("loadstart", function () +{ + // Tell the parent to terminate us. + postMessage("TERMINATE"); + // And wait for it to do so. + while(1) { true; } +}); +xhr.send(null); diff --git a/dom/xhr/tests/test_XHR.html b/dom/xhr/tests/test_XHR.html new file mode 100644 index 000000000..143805a9e --- /dev/null +++ b/dom/xhr/tests/test_XHR.html @@ -0,0 +1,393 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for XMLHttpRequest</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="gen.next();"> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.7"> +"use strict"; +SimpleTest.waitForExplicitFinish(); + +var gen = runTests(); +function continueTest() { gen.next(); } + +function runTests() { + +var path = "/tests/dom/xhr/tests/"; + +var passFiles = [['file_XHR_pass1.xml', 'GET', 200, 'OK', 'text/xml'], + ['file_XHR_pass2.txt', 'GET', 200, 'OK', 'text/plain'], + ['file_XHR_pass3.txt', 'GET', 200, 'OK', 'text/plain'], + ['data:text/xml,%3Cres%3Ehello%3C/res%3E%0A', 'GET', 200, 'OK', 'text/xml'], + ['data:text/plain,hello%20pass%0A', 'GET', 200, 'OK', 'text/plain'], + ['data:,foo', 'GET', 200, 'OK', 'text/plain;charset=US-ASCII', 'foo'], + ['data:text/plain;base64,Zm9v', 'GET', 200, 'OK', 'text/plain', 'foo'], + ['data:text/plain,foo#bar', 'GET', 200, 'OK', 'text/plain', 'foo'], + ['data:text/plain,foo%23bar', 'GET', 200, 'OK', 'text/plain', 'foo#bar'], + ]; + +var blob = new Blob(["foo"], { type: "text/plain" }); +var blobURL = URL.createObjectURL(blob); + +passFiles.push([blobURL, 'GET', 200, 'OK', 'text/plain', 'foo']); + +var failFiles = [['//example.com' + path + 'file_XHR_pass1.xml', 'GET'], + ['ftp://localhost' + path + 'file_XHR_pass1.xml', 'GET'], + ['file_XHR_fail1.txt', 'GET'], + ]; + +for (i = 0; i < passFiles.length; ++i) { + // Function to give our hacked is() a scope + (function(oldIs) { + function is(actual, expected, message) { + oldIs(actual, expected, message + " for " + passFiles[i][0]); + } + xhr = new XMLHttpRequest(); + is(xhr.getResponseHeader("Content-Type"), null, "should be null"); + is(xhr.getAllResponseHeaders(), "", "should be empty string"); + is(xhr.responseType, "", "wrong initial responseType"); + xhr.open(passFiles[i][1], passFiles[i][0], false); + xhr.send(null); + is(xhr.status, passFiles[i][2], "wrong status"); + is(xhr.statusText, passFiles[i][3], "wrong statusText"); + is(xhr.getResponseHeader("Content-Type"), passFiles[i][4], "wrong content type"); + var headers = xhr.getAllResponseHeaders(); + ok(/(?:^|\n)Content-Type:\s*([^\r\n]*)\r\n/i.test(headers) && + RegExp.$1 === passFiles[i][4], "wrong response headers"); + if (xhr.responseXML) { + is((new XMLSerializer()).serializeToString(xhr.responseXML.documentElement), + passFiles[i][5] || "<res>hello</res>", "wrong responseXML"); + is(xhr.response, passFiles[i][5] || "<res>hello</res>\n", "wrong response"); + } + else { + is(xhr.responseText, passFiles[i][5] || "hello pass\n", "wrong responseText"); + is(xhr.response, passFiles[i][5] || "hello pass\n", "wrong response"); + } + })(is); +} + +URL.revokeObjectURL(blobURL); + +for (i = 0; i < failFiles.length; ++i) { + xhr = new XMLHttpRequest(); + var didthrow = false; + try { + xhr.open(failFiles[i][1], failFiles[i][0], false); + xhr.send(null); + } + catch (e) { + didthrow = true; + } + if (!didthrow) { + is(xhr.status, 301, "wrong status"); + is(xhr.responseText, "redirect file\n", "wrong response"); + } + else { + ok(1, "should have thrown or given incorrect result"); + } +} + +function checkResponseTextAccessThrows(xhr) { + var didthrow = false; + try { xhr.responseText } catch (e) { didthrow = true; } + ok(didthrow, "should have thrown when accessing responseText"); +} +function checkResponseXMLAccessThrows(xhr) { + var didthrow = false; + try { xhr.responseXML } catch (e) { didthrow = true; } + ok(didthrow, "should have thrown when accessing responseXML"); +} +function checkSetResponseType(xhr, type) { + var didthrow = false; + try { xhr.responseType = type; } catch (e) { didthrow = true; } + is(xhr.responseType, type, "responseType should be " + type); + ok(!didthrow, "should not have thrown when setting responseType"); +} +function checkSetResponseTypeThrows(xhr, type) { + var didthrow = false; + try { xhr.responseType = type; } catch (e) { didthrow = true; } + ok(didthrow, "should have thrown when setting responseType"); +} +function checkOpenThrows(xhr, method, url, async) { + var didthrow = false; + try { xhr.open(method, url, async); } catch (e) { didthrow = true; } + ok(didthrow, "should have thrown when open is called"); +} + +// test if setting responseType before calling open() works +xhr = new XMLHttpRequest(); +checkSetResponseType(xhr, ""); +checkSetResponseType(xhr, "text"); +checkSetResponseType(xhr, "document"); +checkSetResponseType(xhr, "arraybuffer"); +checkSetResponseType(xhr, "blob"); +checkSetResponseType(xhr, "json"); +checkSetResponseType(xhr, "moz-chunked-text"); +checkSetResponseType(xhr, "moz-chunked-arraybuffer"); +checkOpenThrows(xhr, "GET", "file_XHR_pass2.txt", false); + +// test response (sync, responseType is not changeable) +xhr = new XMLHttpRequest(); +xhr.open("GET", 'file_XHR_pass2.txt', false); +checkSetResponseTypeThrows(xhr, ""); +checkSetResponseTypeThrows(xhr, "text"); +checkSetResponseTypeThrows(xhr, "document"); +checkSetResponseTypeThrows(xhr, "arraybuffer"); +checkSetResponseTypeThrows(xhr, "blob"); +checkSetResponseTypeThrows(xhr, "json"); +checkSetResponseTypeThrows(xhr, "moz-chunked-text"); +checkSetResponseTypeThrows(xhr, "moz-chunked-arraybuffer"); +xhr.send(null); +checkSetResponseTypeThrows(xhr, "document"); +is(xhr.status, 200, "wrong status"); +is(xhr.response, "hello pass\n", "wrong response"); + +// test response (responseType='document') +xhr = new XMLHttpRequest(); +xhr.open("GET", 'file_XHR_pass1.xml'); +xhr.responseType = 'document'; +xhr.onloadend = continueTest; +xhr.send(null); +yield undefined; +checkSetResponseTypeThrows(xhr, "document"); +is(xhr.status, 200, "wrong status"); +checkResponseTextAccessThrows(xhr); +is((new XMLSerializer()).serializeToString(xhr.response.documentElement), + "<res>hello</res>", + "wrong response"); + +// test response (responseType='text') +xhr = new XMLHttpRequest(); +xhr.open("GET", 'file_XHR_pass2.txt'); +xhr.responseType = 'text'; +xhr.onloadend = continueTest; +xhr.send(null); +yield undefined; +is(xhr.status, 200, "wrong status"); +checkResponseXMLAccessThrows(xhr); +is(xhr.response, "hello pass\n", "wrong response"); + +// test response (responseType='arraybuffer') +function arraybuffer_equals_to(ab, s) { + is(ab.byteLength, s.length, "wrong arraybuffer byteLength"); + + var u8v = new Uint8Array(ab); + is(String.fromCharCode.apply(String, u8v), s, "wrong values"); +} + +// with a simple text file +xhr = new XMLHttpRequest(); +xhr.open("GET", 'file_XHR_pass2.txt'); +xhr.responseType = 'arraybuffer'; +xhr.onloadend = continueTest; +xhr.send(null); +yield undefined; +is(xhr.status, 200, "wrong status"); +checkResponseTextAccessThrows(xhr); +checkResponseXMLAccessThrows(xhr); +var ab = xhr.response; +ok(ab != null, "should have a non-null arraybuffer"); +arraybuffer_equals_to(ab, "hello pass\n"); + +// test reusing the same XHR (Bug 680816) +xhr.open("GET", 'file_XHR_binary1.bin'); +xhr.responseType = 'arraybuffer'; +xhr.onloadend = continueTest; +xhr.send(null); +yield undefined; +is(xhr.status, 200, "wrong status"); +var ab2 = xhr.response; +ok(ab2 != null, "should have a non-null arraybuffer"); +ok(ab2 != ab, "arraybuffer on XHR reuse should be distinct"); +arraybuffer_equals_to(ab, "hello pass\n"); +arraybuffer_equals_to(ab2, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb"); + +// with a binary file +xhr = new XMLHttpRequest(); +xhr.open("GET", 'file_XHR_binary1.bin'); +xhr.responseType = 'arraybuffer'; +xhr.onloadend = continueTest; +xhr.send(null); +yield undefined; +is(xhr.status, 200, "wrong status"); +checkResponseTextAccessThrows(xhr); +checkResponseXMLAccessThrows(xhr); +ab = xhr.response; +ok(ab != null, "should have a non-null arraybuffer"); +arraybuffer_equals_to(ab, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb"); +is(xhr.response, xhr.response, "returns the same ArrayBuffer"); + +// test response (responseType='json') +var xhr = new XMLHttpRequest(); +xhr.open("POST", 'responseIdentical.sjs'); +xhr.responseType = 'json'; +var jsonObjStr = JSON.stringify({title: "aBook", author: "john"}); +xhr.onloadend = continueTest; +xhr.send(jsonObjStr); +yield undefined; +is(xhr.status, 200, "wrong status"); +checkResponseTextAccessThrows(xhr); +checkResponseXMLAccessThrows(xhr); +is(JSON.stringify(xhr.response), jsonObjStr, "correct result"); +is(xhr.response, xhr.response, "returning the same object on each access"); + +// with invalid json +var xhr = new XMLHttpRequest(); +xhr.open("POST", 'responseIdentical.sjs'); +xhr.responseType = 'json'; +xhr.onloadend = continueTest; +xhr.send("{"); +yield undefined; +is(xhr.status, 200, "wrong status"); +checkResponseTextAccessThrows(xhr); +checkResponseXMLAccessThrows(xhr); +is(xhr.response, null, "Bad JSON should result in null response."); +is(xhr.response, null, "Bad JSON should result in null response even 2nd time."); + +// Test status/statusText in all readyStates +xhr = new XMLHttpRequest(); +function checkXHRStatus() { + if (xhr.readyState == xhr.UNSENT || xhr.readyState == xhr.OPENED) { + is(xhr.status, 0, "should be 0 before getting data"); + is(xhr.statusText, "", "should be empty before getting data"); + } + else { + is(xhr.status, 200, "should be 200 when we have data"); + is(xhr.statusText, "OK", "should be OK when we have data"); + } +} +checkXHRStatus(); +xhr.open("GET", 'file_XHR_binary1.bin'); +checkXHRStatus(); +xhr.responseType = 'arraybuffer'; +xhr.send(null); +xhr.onreadystatechange = continueTest; +while (xhr.readyState != 4) { + checkXHRStatus(); + yield undefined; +} +checkXHRStatus(); + +// test response (responseType='blob') +var responseTypes = ['blob', 'moz-blob']; +for (var i = 0; i < responseTypes.length; i++) { + var t = responseTypes[i]; + // with a simple text file + xhr = new XMLHttpRequest(); + xhr.open("GET", 'file_XHR_pass2.txt'); + xhr.responseType = t; + xhr.onloadend = continueTest; + xhr.send(null); + yield undefined; + is(xhr.status, 200, "wrong status"); + checkResponseTextAccessThrows(xhr); + checkResponseXMLAccessThrows(xhr); + var b = xhr.response; + ok(b, "should have a non-null blob"); + ok(b instanceof Blob, "should be a Blob"); + ok(!(b instanceof File), "should not be a File"); + is(b.size, "hello pass\n".length, "wrong blob size"); + + var fr = new FileReader(); + fr.onload = continueTest; + fr.readAsBinaryString(b); + yield undefined; + ok(fr.result, "hello pass\n", "wrong values"); + + // with a binary file + xhr = new XMLHttpRequest(); + xhr.open("GET", 'file_XHR_binary1.bin', true); + xhr.send(null); + xhr.onreadystatechange = continueTest; + while(xhr.readyState != 2) + yield undefined; + + is(xhr.status, 200, "wrong status"); + xhr.responseType = t; + + while(xhr.readyState != 4) + yield undefined; + + xhr.onreadystatechange = null; + + b = xhr.response; + ok(b != null, "should have a non-null blob"); + is(b.size, 12, "wrong blob size"); + + fr = new FileReader(); + fr.readAsBinaryString(b); + xhr = null; // kill the XHR object + b = null; + SpecialPowers.gc(); + fr.onload = continueTest; + yield undefined; + is(fr.result, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb", "wrong values"); + + // with a larger binary file + xhr = new XMLHttpRequest(); + xhr.open("GET", 'file_XHR_binary2.bin', true); + xhr.responseType = t; + xhr.send(null); + xhr.onreadystatechange = continueTest; + + while (xhr.readyState != 4) + yield undefined; + + xhr.onreadystatechange = null; + + var b = xhr.response; + ok(b != null, "should have a non-null blob"); + is(b.size, 65536, "wrong blob size"); + + fr = new FileReader(); + fr.readAsArrayBuffer(b); + fr.onload = continueTest; + xhr = null; // kill the XHR object + b = null; + SpecialPowers.gc(); + yield undefined; + + var u8 = new Uint8Array(fr.result); + for (var i = 0; i < 65536; i++) { + if (u8[i] !== (i & 255)) { + break; + } + } + is(i, 65536, "wrong value at offset " + i); +} + +var client = new XMLHttpRequest(); +client.open("GET", "file_XHR_pass1.xml", true); +client.send(); +client.onreadystatechange = function() { + if(client.readyState == 4) { + try { + is(client.responseXML, null, "responseXML should be null."); + is(client.responseText, "", "responseText should be empty string."); + is(client.response, "", "response should be empty string."); + is(client.status, 0, "status should be 0."); + is(client.statusText, "", "statusText should be empty string."); + is(client.getAllResponseHeaders(), "", + "getAllResponseHeaders() should return empty string."); + } catch(ex) { + ok(false, "Shouldn't throw! [" + ex + "]"); + } + } +} +client.abort(); + +SimpleTest.finish(); +yield undefined; + +} /* runTests */ +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHRDocURI.html b/dom/xhr/tests/test_XHRDocURI.html new file mode 100644 index 000000000..e3bd1d311 --- /dev/null +++ b/dom/xhr/tests/test_XHRDocURI.html @@ -0,0 +1,513 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=459470 +--> +<head> + <title>XMLHttpRequest return document URIs</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <base href="http://example.org/"> +</head> +<body onload="startTest();"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=459470">Mozilla Bug 459470</a><br /> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=859095">Mozilla Bug 859095</a> + +<p id="display"> +<iframe id=loader></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +SimpleTest.waitForExplicitFinish(); +var gen; + +function startTest() { + // The test uses history API, so don't do anything before load event has been + // handled. + SimpleTest.executeSoon(function() { + gen = runTest(); + gen.next(); + }); +} + +function testXMLDocURI(aDoc, aExpects) { + is(aDoc.documentURI, aExpects.documentURI, "wrong url"); + is(aDoc.baseURI, aExpects.baseURI, "wrong base"); + is(aDoc.documentElement.baseURI, aExpects.elementBaseURI, + "wrong base (xml:base)"); +} + +function testChromeXMLDocURI(aDoc, aExpects) { + is(aDoc.documentURI, aExpects.documentURI, "wrong url"); + is(aDoc.documentURIObject.spec, aExpects.documentURI, + "wrong url (.documentObjectURI)"); + is(aDoc.baseURI, aExpects.baseURI, "wrong base"); + is(aDoc.baseURIObject.spec, aExpects.baseURI, + "wrong base (.baseURIObject)"); + is(aDoc.documentElement.baseURI, aExpects.elementBaseURI, + "wrong base (xml:base)"); + is(aDoc.documentElement.baseURIObject.spec, aExpects.elementBaseURI, + "wrong base (.baseURIObject, xml:base)"); +} + +function testHTMLDocURI(aDoc, aExpects) { + is(aDoc.documentURI, aExpects.documentURI, "wrong url"); + is(aDoc.baseURI, aExpects.baseURI, "wrong base"); + + var base = aDoc.createElement("base"); + var newBaseURI = "http://www.example.com/"; + base.href = newBaseURI; + aDoc.head.appendChild(base); + is(aDoc.baseURI, newBaseURI, "wrong base (after <base> changed)"); +} + +function testChromeHTMLDocURI(aDoc, aNonChromeBaseURI, aExpects) { + is(aDoc.documentURI, aExpects.documentURI, "wrong url"); + is(aDoc.documentURIObject.spec, aExpects.documentURI, + "wrong url (.documentURIObject)"); + is(aDoc.baseURI, aExpects.baseURI, "wrong base"); + is(aDoc.baseURIObject.spec, aExpects.baseURI, + "wrong url (.baseURIObject)"); + + aDoc.body.setAttributeNS("http://www.w3.org/XML/1998/namespace", "base", + aNonChromeBaseURI); + is(aDoc.body.baseURI, aNonChromeBaseURI, + "wrong base (doc base and xml:base are same)"); + is(aDoc.body.baseURIObject.spec, aNonChromeBaseURI, + "wrong base (.baseURIObject, doc base and xml:base are same)") + var attr = aDoc.getElementById("data").getAttributeNode("id"); + is(attr.baseURI, aNonChromeBaseURI, + "wrong attr base (doc base and xml:base are same)") + is(attr.baseURIObject.spec, aNonChromeBaseURI, + "wrong attr base (.baseURIObject, doc base and xml:base are same)") + + var base = aDoc.createElement("base"); + var newBaseURI = "http://www.example.com/"; + base.href = newBaseURI; + aDoc.head.appendChild(base); + is(aDoc.baseURI, newBaseURI, "wrong base (after <base> changed)"); + is(aDoc.baseURIObject.spec, newBaseURI, + "wrong base (.baseURIObject, after <base> changed)"); +} + +function testCloneDocURI(aDoc) { + var clone = aDoc.cloneNode(true); + is(clone.documentURI, aDoc.documentURI, "wrong url (clone)"); + is(clone.baseURI, aDoc.baseURI, "wrong base (clone)"); +} + +function runTest() { + is(document.baseURI, "http://example.org/", "wrong doc baseURI"); + + // use content XHR and access URI properties from content privileged script + xhr = new XMLHttpRequest; + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml"); + xhr.onreadystatechange = function(e) { + if (!xhr.responseXML) { + return; + } + var expects = { + documentURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml", + baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml", + elementBaseURI: "http://www.example.com/" + }; + testXMLDocURI(xhr.responseXML, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html"); + xhr.responseType = "document"; + xhr.onreadystatechange = function(e) { + if (!xhr.response) { + return; + } + var expects = { + documentURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html", + baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html" + }; + testHTMLDocURI(xhr.response, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.text"); + xhr.onreadystatechange = function(e) { + is(xhr.responseXML, null, "should not have document"); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"); + xhr.onreadystatechange = function(e) { + if (!xhr.responseXML) { + return; + } + var expects = { + documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml", + baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml", + elementBaseURI: "http://www.example.com/" + }; + testXMLDocURI(xhr.responseXML, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html"); + xhr.responseType = "document"; + xhr.onreadystatechange = function(e) { + if (!xhr.response) { + return; + } + var expects = { + documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html", + baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html" + }; + testHTMLDocURI(xhr.response, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"); + xhr.onreadystatechange = function(e) { + if (!xhr.responseXML) { + return; + } + var expects = { + documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml", + baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml", + elementBaseURI: "http://www.example.com/" + }; + testXMLDocURI(xhr.responseXML, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html"); + xhr.responseType = "document"; + xhr.onreadystatechange = function(e) { + if (!xhr.response) { + return; + } + var expects = { + documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html", + baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html" + }; + testHTMLDocURI(xhr.response, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.text"); + xhr.onreadystatechange = function(e) { + is(xhr.responseXML, null, "should not have document"); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + + // use content XHR and access URI properties from chrome privileged script + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml"); + xhr.onreadystatechange = function(e) { + if (!xhr.responseXML) { + return; + } + var expects = { + documentURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml", + baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml", + elementBaseURI: "http://www.example.com/" + }; + var xml = SpecialPowers.wrap(xhr.responseXML); + testChromeXMLDocURI(xml, expects); + testCloneDocURI(xml); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html"); + xhr.responseType = "document"; + xhr.onreadystatechange = function(e) { + if (!xhr.response) { + return; + } + var expects = { + documentURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html", + baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html" + }; + var doc = SpecialPowers.wrap(xhr.response); + testChromeHTMLDocURI(doc, "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html", expects); + testCloneDocURI(doc); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"); + xhr.onreadystatechange = function(e) { + if (!xhr.responseXML) { + return; + } + var expects = { + documentURI: document.documentURI, + baseURI: document.baseURI, + elementBaseURI: "http://www.example.com/" + }; + var xml = SpecialPowers.wrap(xhr.responseXML); + testChromeXMLDocURI(xml, expects); + testCloneDocURI(xml); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html"); + xhr.responseType = "document"; + xhr.onreadystatechange = function(e) { + if (!xhr.response) { + return; + } + var expects = { + documentURI: document.documentURI, + baseURI: document.baseURI + }; + var doc = SpecialPowers.wrap(xhr.response); + testChromeHTMLDocURI(doc, "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html", expects); + testCloneDocURI(doc); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"); + xhr.onreadystatechange = function(e) { + if (!xhr.responseXML) { + return; + } + var expects = { + documentURI: document.documentURI, + baseURI: document.baseURI, + elementBaseURI: "http://www.example.com/" + }; + var xml = SpecialPowers.wrap(xhr.responseXML); + testChromeXMLDocURI(xml, expects); + testCloneDocURI(xml); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest; + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html"); + xhr.responseType = "document"; + xhr.onreadystatechange = function(e) { + if (!xhr.response) { + return; + } + var expects = { + documentURI: document.documentURI, + baseURI: document.baseURI + }; + var doc = SpecialPowers.wrap(xhr.response); + testChromeHTMLDocURI(doc, "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html", expects); + testCloneDocURI(doc); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + + // use the systemXHR special privilege + SpecialPowers.addPermission("systemXHR", true, document); + xhr = new XMLHttpRequest({mozAnon: false, mozSystem: true}); + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml"); + xhr.onreadystatechange = function(e) { + if (!xhr.responseXML) { + return; + } + var expects = { + documentURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml", + baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml", + elementBaseURI: "http://www.example.com/" + }; + testXMLDocURI(xhr.responseXML, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest({mozAnon: false, mozSystem: true}); + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html"); + xhr.responseType = "document"; + xhr.onreadystatechange = function(e) { + if (!xhr.response) { + return; + } + var expects = { + documentURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html", + baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.html" + }; + testHTMLDocURI(xhr.response, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest({mozAnon: false, mozSystem: true}); + xhr.open("GET", "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"); + xhr.onreadystatechange = function(e) { + if (!xhr.responseXML) { + return; + } + var expects = { + documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml", + baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml", + elementBaseURI: "http://www.example.com/" + }; + testXMLDocURI(xhr.responseXML, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest({mozAnon: false, mozSystem: true}); + xhr.open("GET", "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html"); + xhr.responseType = "document"; + xhr.onreadystatechange = function(e) { + if (!xhr.response) { + return; + } + var expects = { + documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html", + baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html" + }; + testHTMLDocURI(xhr.response, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest({mozAnon: false, mozSystem: true}); + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"); + xhr.onreadystatechange = function(e) { + if (!xhr.responseXML) { + return; + } + var expects = { + documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml", + baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml", + elementBaseURI: "http://www.example.com/" + }; + testXMLDocURI(xhr.responseXML, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + xhr = new XMLHttpRequest({mozAnon: false, mozSystem: true}); + xhr.open("GET", "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.sjs?url=http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html"); + xhr.responseType = "document"; + xhr.onreadystatechange = function(e) { + if (!xhr.response) { + return; + } + var expects = { + documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html", + baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.html" + }; + testHTMLDocURI(xhr.response, expects); + if (xhr.readyState == 4) { + gen.next(); + } + }; + xhr.send(); + yield undefined; + + history.pushState({}, "pushStateTest", window.location.href + "/pushStateTest"); + ok(document.documentURI.indexOf("pushStateTest") > -1); + + var chromeDoc = SpecialPowers.wrap(document); + ok(chromeDoc.documentURI.indexOf("pushStateTest") > -1); + + SimpleTest.executeSoon(function() { gen.next(); }); + + yield undefined; + + history.back(); + SimpleTest.executeSoon(function() { gen.next(); }); + + yield undefined; + + SimpleTest.finish(); + SpecialPowers.removePermission("systemXHR", document); + yield undefined; +} + +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHRResponseURL.html b/dom/xhr/tests/test_XHRResponseURL.html new file mode 100644 index 000000000..17e8c627a --- /dev/null +++ b/dom/xhr/tests/test_XHRResponseURL.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=998076 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 998076</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript" src="file_XHRResponseURL.js"></script> + <script type="application/javascript"> + +/** Test for Bug 998076 **/ +"use strict"; + +window.addEventListener("message", function (aEvent) { + var data = aEvent.data; + if (data === "done") { + SimpleTest.finish(); + return; + } + if (data === "start") { + return; + } + if (data.type === "is") { + SimpleTest.is(data.actual, data.expected, data.message); + window.postMessage("pong", "*"); + return; + } + if (data.type === "ok") { + SimpleTest.ok(data.bool, data.message); + window.postMessage("pong", "*"); + return; + } + if (data.type === "info") { + SimpleTest.info(data.message); + window.postMessage("pong", "*"); + return; + } + if (data.type === "todo") { + SimpleTest.todo(data.bool, data.message); + window.postMessage("pong", "*"); + return; + } + if (data.type === "todo_is") { + SimpleTest.todo_is(data.actual, data.expected, data.message); + window.postMessage("pong", "*"); + return; + } +}); + +function runTests() { + SimpleTest.waitForExplicitFinish(); + window.postMessage("start", "*"); +} + + </script> +</head> +<body onload="runTests()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=998076">Mozilla Bug 998076</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHRSendData.html b/dom/xhr/tests/test_XHRSendData.html new file mode 100644 index 000000000..c210efc9c --- /dev/null +++ b/dom/xhr/tests/test_XHRSendData.html @@ -0,0 +1,267 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=464848 +--> +<head> + <title>XMLHttpRequest send data and headers</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="createFiles();"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=464848">Mozilla Bug 464848</a> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> +SimpleTest.waitForExplicitFinish(); + +var testData = "blahblahblahblahblahblahblaaaaaaaah. blah."; +var extensions = [".txt",".png",".jpg",".gif",".xml", "noext"]; +var fileTypes = ["text/plain", "image/png", "image/jpeg", "image/gif", "text/xml", null]; +var gen = runTests(); +var testDOMFiles; + +function createFiles() { + var filesToCreate = new Array(); + extensions.forEach(function (extension) { + filesToCreate.push({name: "testfile" + extension, data: testData}); + }); + SpecialPowers.createFiles(filesToCreate, + function (files) { + testDOMFiles = files; + gen.next(); + }, + function (msg) { + testDOMFiles = new Array; + ok(false, "File creation error: " + msg); + gen.next(); + }); +}; + + +function continueTest() { gen.next(); } + +function runTests() { +xhr = new XMLHttpRequest(); +xhr.open("GET", "file_XHRSendData_doc.xml", false); +xhr.send(); +testDoc1 = xhr.responseXML; +is(testDoc1.inputEncoding, "windows-1252", "wrong encoding"); + +testDoc2 = document.implementation.createDocument("", "", null); +testDoc2.appendChild(testDoc2.createComment(" doc 2 ")); +testDoc2.appendChild(testDoc2.createElement("res")); +testDoc2.documentElement.appendChild(testDoc2.createTextNode("text")); +is(testDoc2.inputEncoding, "UTF-8", "wrong encoding"); + +// arraybuffer test objects +var shortArray = new ArrayBuffer(1); +var shortInt8View = new Uint8Array(shortArray); +shortInt8View[0] = 3; + +var longArray = new ArrayBuffer(512); +var longInt8View = new Uint8Array(longArray); +for (var i = 0; i < longInt8View.length; i++) { + longInt8View[i] = i % 255; +} + +// arraybufferview test objects +var longArraySlice = longArray.slice(256, 384); +var longInt32View1 = new Int32Array(longArraySlice) +var longInt32View2 = new Int32Array(longArray, 256, 32) +var longInt16View1 = new Uint16Array(longArraySlice) +var longInt16View2 = new Uint16Array(longArray, 256, 64) +var longInt8View1 = new Int8Array(longArraySlice) +var longInt8View2 = new Int8Array(longArray, 256, 128) + +tests = [{ body: null, + resBody: "", + }, + { body: undefined, + resBody: "", + }, + { body: "hi", + resBody: "hi", + resContentType: "text/plain;charset=UTF-8", + }, + { body: "r\xe4ksm\xf6rg\xe5s", + resBody: "r\xc3\xa4ksm\xc3\xb6rg\xc3\xa5s", + resContentType: "text/plain;charset=UTF-8", + }, + { body: "hi", + contentType: "", + resBody: "hi", + resContentType: "text/plain;charset=UTF-8", + }, + { body: "hi", + contentType: "foo/bar", + resBody: "hi", + resContentType: "foo/bar", + }, + { body: "hi", + contentType: "foo/bar; baz=bin", + resBody: "hi", + resContentType: "foo/bar; baz=bin", + }, + { body: "hi", + contentType: "foo/bar; charset=ascii; baz=bin", + resBody: "hi", + resContentType: "foo/bar; charset=UTF-8; baz=bin", + }, + { body: "hi", + contentType: "foo/bar; charset=uTf-8", + resBody: "hi", + resContentType: "foo/bar; charset=uTf-8", + }, + { body: testDoc1, + resBody: "<!-- comment -->\n<out>hi</out>", + resContentType: "application/xml;charset=UTF-8", + }, + { body: testDoc1, + contentType: "foo/bar", + resBody: "<!-- comment -->\n<out>hi</out>", + resContentType: "foo/bar", + }, + { body: testDoc1, + contentType: "foo/bar; charset=ascii; baz=bin", + resBody: "<!-- comment -->\n<out>hi</out>", + resContentType: "foo/bar; charset=UTF-8; baz=bin", + }, + { body: testDoc1, + contentType: "foo/bar; charset=wIndows-1252", + resBody: "<!-- comment -->\n<out>hi</out>", + resContentType: "foo/bar; charset=UTF-8", + }, + { body: testDoc2, + resBody: "<!-- doc 2 -->\n<res>text</res>", + resContentType: "application/xml;charset=UTF-8", + }, + { body: testDoc2, + contentType: "foo/bar", + resBody: "<!-- doc 2 -->\n<res>text</res>", + resContentType: "foo/bar", + }, + { body: testDoc2, + contentType: "foo/bar; charset=ascii; baz=bin", + resBody: "<!-- doc 2 -->\n<res>text</res>", + resContentType: "foo/bar; charset=UTF-8; baz=bin", + }, + { body: testDoc2, + contentType: "foo/bar; charset=uTf-8", + resBody: "<!-- doc 2 -->\n<res>text</res>", + resContentType: "foo/bar; charset=uTf-8", + }, + { //will trigger a redirect test server-side + body: ("TEST_REDIRECT_STR&url=" + window.location.host + window.location.pathname), + redirect: true, + }, + { body: shortArray, + resBody: shortArray, + resType: "arraybuffer" + }, + { body: longArray, + resBody: longArray, + resType: "arraybuffer" + }, + { body: longInt32View1, + resBody: longArraySlice, + resType: "arraybuffer" + }, + { body: longInt32View2, + resBody: longArraySlice, + resType: "arraybuffer" + }, + { body: longInt16View1, + resBody: longArraySlice, + resType: "arraybuffer" + }, + { body: longInt16View2, + resBody: longArraySlice, + resType: "arraybuffer" + }, + { body: longInt8View1, + resBody: longArraySlice, + resType: "arraybuffer" + }, + { body: longInt8View2, + resBody: longArraySlice, + resType: "arraybuffer" + }, + ]; + +for (var i = 0; i < testDOMFiles.length; i++) { + tests.push({ body: testDOMFiles[i], + resBody: testData, + resContentType: fileTypes[i], + resContentLength: testData.length, + }); +} + +try { + for (test of tests) { + xhr = new XMLHttpRequest; + xhr.open("POST", "file_XHRSendData.sjs", !!test.resType); + if (test.contentType) + xhr.setRequestHeader("Content-Type", test.contentType); + if (test.resType) { + xhr.responseType = test.resType; + xhr.onloadend = continueTest; + } + xhr.send(test.body); + if (test.resType) + yield undefined; + + if (test.resContentType) { + is(xhr.getResponseHeader("Result-Content-Type"), test.resContentType, + "Wrong Content-Type sent"); + } + else { + is(xhr.getResponseHeader("Result-Content-Type"), null); + } + + if (test.resContentLength) { + is(xhr.getResponseHeader("Result-Content-Length"), + String(test.resContentLength), + "Wrong Content-Length sent"); + } + + if (test.resType == "arraybuffer") { + is_identical_arraybuffer(xhr.response, test.resBody); + } + else if (test.body instanceof Document) { + is(xhr.responseText.replace("\r\n", "\n"), test.resBody, "Wrong body"); + } + else if (!test.redirect) { + is(xhr.responseText, test.resBody, "Wrong body"); + } + else { + // If we're testing redirect, determine whether the body is + // this document by looking for the relevant bug url + is(xhr.responseText.indexOf("https://bugzilla.mozilla.org/show_bug.cgi?id=464848") >= 0, true, + "Wrong page for redirect"); + } + } +} catch (e) { +} + +function is_identical_arraybuffer(ab1, ab2) { + is(ab1.byteLength, ab2.byteLength, "arraybuffer byteLengths not equal"); + u8v1 = new Uint8Array(ab1); + u8v2 = new Uint8Array(ab2); + is(String.fromCharCode.apply(String, u8v1), + String.fromCharCode.apply(String, u8v2), "arraybuffer values not equal"); +} + +SimpleTest.finish(); +yield undefined; +} /* runTests */ + +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHR_anon.html b/dom/xhr/tests/test_XHR_anon.html new file mode 100644 index 000000000..ed9271a04 --- /dev/null +++ b/dom/xhr/tests/test_XHR_anon.html @@ -0,0 +1,180 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Test for XMLHttpRequest with system privileges</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="setup();"> +<p id="display"> +<iframe id="loader"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +// An XHR with the anon flag set will not send cookie and auth information. +const TEST_URL = "http://example.com/tests/dom/xhr/tests/file_XHR_anon.sjs"; +document.cookie = "foo=bar"; + +let am = { + authMgr: null, + + init: function() { + this.authMgr = SpecialPowers.Cc["@mozilla.org/network/http-auth-manager;1"] + .getService(SpecialPowers.Ci.nsIHttpAuthManager) + }, + + addIdentity: function() { + this.authMgr.setAuthIdentity("http", "example.com", -1, "basic", "testrealm", + "", "example.com", "user1", "password1"); + }, + + tearDown: function() { + this.authMgr.clearAll(); + }, +} + +var tests = [ test1, test2, test2a, test3, test3, test3, test4, test4, test4, test5, test5, test5 ]; + +function runTests() { + if (!tests.length) { + am.tearDown(); + + // Resetting the cookie. + document.cookie = "foo=; expires=Thu, 01 Jan 1970 00:00:00 GMT"; + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +function test1() { + am.addIdentity(); + + let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + is(xhr.mozAnon, true, "test1: .mozAnon == true"); + xhr.open("GET", TEST_URL); + xhr.onload = function onload() { + is(xhr.status, 200, "test1: " + xhr.responseText); + am.tearDown(); + runTests(); + }; + xhr.onerror = function onerror() { + ok(false, "Got an error event!"); + am.tearDown(); + runTests(); + } + xhr.send(); +} + +function test2() { + am.addIdentity(); + + let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + is(xhr.mozAnon, true, "test2: .mozAnon == true"); + xhr.open("GET", TEST_URL + "?expectAuth=true", true, + "user2name", "pass2word"); + xhr.onload = function onload() { + is(xhr.status, 200, "test2: " + xhr.responseText); + let response = JSON.parse(xhr.responseText); + is(response.authorization, "Basic dXNlcjJuYW1lOnBhc3Myd29yZA=="); + am.tearDown(); + runTests(); + }; + xhr.onerror = function onerror() { + ok(false, "Got an error event!"); + am.tearDown(); + runTests(); + } + xhr.send(); +} + +function test2a() { + am.addIdentity(); + + let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + is(xhr.mozAnon, true, "test2: .mozAnon == true"); + xhr.open("GET", TEST_URL + "?expectAuth=true", true, + "user1", "pass2word"); + xhr.onload = function onload() { + is(xhr.status, 200, "test2: " + xhr.responseText); + let response = JSON.parse(xhr.responseText); + is(response.authorization, "Basic dXNlcjE6cGFzczJ3b3Jk"); + am.tearDown(); + runTests(); + }; + xhr.onerror = function onerror() { + ok(false, "Got an error event!"); + am.tearDown(); + runTests(); + } + xhr.send(); +} + +function test3() { + am.addIdentity(); + + let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + is(xhr.mozAnon, true, "test3: .mozAnon == true"); + xhr.open("GET", TEST_URL + "?expectAuth=true", true); + xhr.onload = function onload() { + is(xhr.status, 401, "test3: " + xhr.responseText); + am.tearDown(); + runTests(); + }; + xhr.onerror = function onerror() { + ok(false, "Got an error event!"); + am.tearDown(); + runTests(); + } + xhr.send(); +} + +function test4() { + let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + is(xhr.mozAnon, true, "test4: .mozAnon == true"); + xhr.open("GET", TEST_URL + "?expectAuth=true", true); + xhr.onload = function onload() { + is(xhr.status, 401, "test4: " + xhr.responseText); + runTests(); + }; + xhr.onerror = function onerror() { + ok(false, "Got an error event!"); + runTests(); + } + xhr.send(); +} + +function test5() { + let xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + is(xhr.mozAnon, true, "test5: .mozAnon == true"); + xhr.open("GET", TEST_URL + "?expectAuth=true", true, + "user2name", "pass2word"); + xhr.onload = function onload() { + is(xhr.status, 200, "test5: " + xhr.responseText); + let response = JSON.parse(xhr.responseText); + is(response.authorization, "Basic dXNlcjJuYW1lOnBhc3Myd29yZA=="); + runTests(); + }; + xhr.onerror = function onerror() { + ok(false, "Got an error event!"); + runTests(); + } + xhr.send(); +} + +function setup() { + am.init(); + SimpleTest.waitForExplicitFinish(); + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], runTests); +} +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHR_header.html b/dom/xhr/tests/test_XHR_header.html new file mode 100644 index 000000000..e213b25c7 --- /dev/null +++ b/dom/xhr/tests/test_XHR_header.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for XMLHttpRequest.GetResponseHeader(foo) byte-inflates the output</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <meta charset="utf-8"> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.7"> +"use strict"; +SimpleTest.waitForExplicitFinish(); + +let xhr = new XMLHttpRequest(); +xhr.open('GET', 'file_XHR_header.sjs', true); +xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + ok(xhr.getResponseHeader('X-Custom-Header-Bytes') == "\xE2\x80\xA6", 'getResponseHeader byte-inflates the output'); + SimpleTest.finish(); + } +} +xhr.send(null); +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHR_onuploadprogress.html b/dom/xhr/tests/test_XHR_onuploadprogress.html new file mode 100644 index 000000000..10c4fd20d --- /dev/null +++ b/dom/xhr/tests/test_XHR_onuploadprogress.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=743666 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 743666</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=743666">Mozilla Bug 743666</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 743666 **/ + +var called = false; +function uploadprogress() +{ + called = true; +} + +var xhr = new XMLHttpRequest(); +xhr.upload.onprogress = uploadprogress; +var event = new ProgressEvent("progress"); +xhr.upload.dispatchEvent(event); +ok(called, + "XMLHttpRequest.upload.onprogress sets upload progress event listener"); + + +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHR_parameters.html b/dom/xhr/tests/test_XHR_parameters.html new file mode 100644 index 000000000..b99bb9dfe --- /dev/null +++ b/dom/xhr/tests/test_XHR_parameters.html @@ -0,0 +1,97 @@ + + +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Test for XMLHttpRequest with system privileges</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="runTests();"> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +function runTests() { + SimpleTest.waitForExplicitFinish(); + + let validParameters = [ + undefined, + null, + {}, + {mozSystem: ""}, + {mozSystem: 0}, + {mozAnon: 1}, + {mozAnon: []}, + {get mozAnon() { return true; }}, + 0, + 7, + Math.PI, + "string", + true, + false, + ]; + + let invalidParameters = [ + {get mozSystem() { throw "Bla"; } }, + ]; + + let havePrivileges = false; + + function testValidParameter(value) { + let xhr; + try { + xhr = new XMLHttpRequest(value); + } catch (ex) { + ok(false, "Got unexpected exception: " + ex); + return; + } + ok(xhr instanceof XMLHttpRequest, "passed " + JSON.stringify(value)); + + // If the page doesnt have privileges to create a system XHR, + // this flag will always be false no matter what is passed. + let expectedAnon = Boolean(value && value.mozAnon); + let expectedSystem = false; + if (havePrivileges) { + expectedSystem = Boolean(value && value.mozSystem); + } + is(xhr.mozAnon, expectedAnon, "testing mozAnon"); + is(xhr.mozSystem, expectedSystem, "testing mozSystem"); + } + + function testInvalidParameter(value) { + let expectedError; + try { + new XMLHttpRequest(value); + ok(false, "invalid parameter did not cause exception: " + + JSON.stringify(value)); + } catch (ex) { + expectedError = ex; + } + ok(expectedError, "invalid parameter raised exception as expected: " + + JSON.stringify(expectedError)) + } + + // Run the tests once without API privileges... + validParameters.forEach(testValidParameter); + invalidParameters.forEach(testInvalidParameter); + + // ...and once with privileges. + havePrivileges = true; + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], function() { + validParameters.forEach(testValidParameter); + invalidParameters.forEach(testInvalidParameter); + + SimpleTest.finish(); + }); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHR_system.html b/dom/xhr/tests/test_XHR_system.html new file mode 100644 index 000000000..1d61e3f77 --- /dev/null +++ b/dom/xhr/tests/test_XHR_system.html @@ -0,0 +1,99 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Test for XMLHttpRequest with system privileges</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="runTests();"> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +let tests = []; + +const PROTECTED_URL = "file:///etc/passwd"; +const REDIRECT_URL = window.location.protocol + "//" + window.location.host + "/tests/dom/xhr/tests/file_XHR_system_redirect.html"; +const CROSSSITE_URL = "http://example.com/tests/dom/xhr/tests/test_XHR_system.html"; + +tests.push(function test_cross_origin() { + // System XHR can load cross-origin resources. + + is(window.location.hostname, "mochi.test", "correct origin"); + + let xhr = new XMLHttpRequest({mozSystem: true}); + is(xhr.mozSystem, true, ".mozSystem == true"); + xhr.open("GET", CROSSSITE_URL); + xhr.onload = function onload() { + is(xhr.status, 200, "correct HTTP status"); + ok(xhr.responseText != null, "HTTP response non-null"); + ok(xhr.responseText.length, "HTTP response not empty"); + runNextTest(); + }; + xhr.onerror = function onerror(event) { + ok(false, "Got an error event: " + event); + runNextTest(); + } + xhr.send(); +}); + +tests.push(function test_file_uri() { + // System XHR is not permitted to access file:/// URIs. + + let xhr = new XMLHttpRequest({mozSystem: true}); + is(xhr.mozSystem, true, ".mozSystem == true"); + xhr.open("GET", PROTECTED_URL); + xhr.onload = function() { + ok(false, "Should not have loaded"); + runNextTest(); + } + xhr.onerror = function(event) { + ok(true, "Got an error event: " + event); + is(xhr.status, 0, "HTTP status is 0"); + runNextTest(); + } + xhr.send(); +}); + +tests.push(function test_redirect_to_file_uri() { + // System XHR won't load file:/// URIs even if an HTTP resource redirects there. + + let xhr = new XMLHttpRequest({mozSystem: true}); + is(xhr.mozSystem, true, ".mozSystem == true"); + xhr.open("GET", REDIRECT_URL); + xhr.onload = function onload() { + ok(false, "Should not have loaded"); + runNextTest(); + }; + xhr.onerror = function onerror(event) { + ok(true, "Got an error event: " + event); + is(xhr.status, 0, "HTTP status is 0"); + runNextTest(); + } + xhr.send(); +}); + + +function runNextTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + tests.shift()(); +} + +function runTests() { + SimpleTest.waitForExplicitFinish(); + + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], runNextTest); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHR_timeout.html b/dom/xhr/tests/test_XHR_timeout.html new file mode 100644 index 000000000..14422d9f4 --- /dev/null +++ b/dom/xhr/tests/test_XHR_timeout.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=525816 +--> +<head> + <title>Test for Bug 525816</title> + <script type="application/javascript" + src="/MochiKit/MochiKit.js"></script> + <script type="application/javascript" + src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" + type="text/css" + href="/tests/SimpleTest/test.css"> +</head> +<body> + +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=525816" + >Mozilla Bug 525816 (XMLHttpRequest timeout)</a> +<p id="display"></p> +<div id="content"> + This test takes over 1 minute to run, probably over 2 minutes. +</div> +<pre id="test"> +<script class="testbody" + type="text/javascript" + src="test_XHR_timeout.js"></script> +<script type="text/javascript"> + window.addEventListener("message", function (event) { + if (event.data == "done") { + SimpleTest.finish(); + return; + } + if (event.data == "start") { + return; + } + if (event.data.type == "is") { + SimpleTest.is(event.data.got, event.data.expected, event.data.msg); + return; + } + if (event.data.type == "ok") { + SimpleTest.ok(event.data.bool, event.data.msg); + return; + } + }); + // Final test harness setup and launch. + (function() { + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestLongerTimeout(TestRequests.length); + SimpleTest.requestFlakyTimeout("This is testing XHR timeouts."); + var msg = "This test will take approximately " + (TestRequests.length * 10) + msg += " seconds to complete, at most."; + document.getElementById("content").firstChild.nodeValue = msg; + window.postMessage("start", "*"); + })(); +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_XHR_timeout.js b/dom/xhr/tests/test_XHR_timeout.js new file mode 100644 index 000000000..203700887 --- /dev/null +++ b/dom/xhr/tests/test_XHR_timeout.js @@ -0,0 +1,342 @@ +/* Notes: + - All times are expressed in milliseconds in this test suite. + - Test harness code is at the end of this file. + - We generate only one request at a time, to avoid overloading the HTTP + request handlers. + */ + +var inWorker = false; +try { + inWorker = !(self instanceof Window); +} catch (e) { + inWorker = true; +} + +function message(data) { + if (inWorker) + self.postMessage(data); + else + self.postMessage(data, "*"); +} + +function is(got, expected, msg) { + var obj = {}; + obj.type = "is"; + obj.got = got; + obj.expected = expected; + obj.msg = msg; + + message(obj); +} + +function ok(bool, msg) { + var obj = {}; + obj.type = "ok"; + obj.bool = bool; + obj.msg = msg; + + message(obj); +} + +/** + * Generate and track results from a XMLHttpRequest with regards to timeouts. + * + * @param {String} id The test description. + * @param {Number} timeLimit The initial setting for the request timeout. + * @param {Number} resetAfter (Optional) The time after sending the request, to + * reset the timeout. + * @param {Number} resetTo (Optional) The delay to reset the timeout to. + * + * @note The actual testing takes place in handleEvent(event). + * The requests are generated in startXHR(). + * + * @note If resetAfter and resetTo are omitted, only the initial timeout setting + * applies. + * + * @constructor + * @implements DOMEventListener + */ +function RequestTracker(async, id, timeLimit /*[, resetAfter, resetTo]*/) { + this.async = async; + this.id = id; + this.timeLimit = timeLimit; + + if (arguments.length > 3) { + this.mustReset = true; + this.resetAfter = arguments[3]; + this.resetTo = arguments[4]; + } + + this.hasFired = false; +} +RequestTracker.prototype = { + /** + * Start the XMLHttpRequest! + */ + startXHR: function() { + var req = new XMLHttpRequest(); + this.request = req; + req.open("GET", "file_XHR_timeout.sjs", this.async); + var me = this; + function handleEvent(e) { return me.handleEvent(e); }; + req.onerror = handleEvent; + req.onload = handleEvent; + req.onabort = handleEvent; + req.ontimeout = handleEvent; + + req.timeout = this.timeLimit; + + if (this.mustReset) { + var resetTo = this.resetTo; + self.setTimeout(function() { + req.timeout = resetTo; + }, this.resetAfter); + } + + req.send(null); + }, + + /** + * Get a message describing this test. + * + * @returns {String} The test description. + */ + getMessage: function() { + var rv = this.id + ", "; + if (this.mustReset) { + rv += "original timeout at " + this.timeLimit + ", "; + rv += "reset at " + this.resetAfter + " to " + this.resetTo; + } + else { + rv += "timeout scheduled at " + this.timeLimit; + } + return rv; + }, + + /** + * Check the event received, and if it's the right (and only) one we get. + * + * @param {DOMProgressEvent} evt An event of type "load" or "timeout". + */ + handleEvent: function(evt) { + if (this.hasFired) { + ok(false, "Only one event should fire: " + this.getMessage()); + return; + } + this.hasFired = true; + + var type = evt.type, expectedType; + // The XHR responds after 3000 milliseconds with a load event. + var timeLimit = this.mustReset && (this.resetAfter < Math.min(3000, this.timeLimit)) ? + this.resetTo : + this.timeLimit; + if ((timeLimit == 0) || (timeLimit >= 3000)) { + expectedType = "load"; + } + else { + expectedType = "timeout"; + } + is(type, expectedType, this.getMessage()); + TestCounter.testComplete(); + } +}; + +/** + * Generate and track XMLHttpRequests which will have abort() called on. + * + * @param shouldAbort {Boolean} True if we should call abort at all. + * @param abortDelay {Number} The time in ms to wait before calling abort(). + */ +function AbortedRequest(shouldAbort, abortDelay) { + this.shouldAbort = shouldAbort; + this.abortDelay = abortDelay; + this.hasFired = false; +} +AbortedRequest.prototype = { + /** + * Start the XMLHttpRequest! + */ + startXHR: function() { + var req = new XMLHttpRequest(); + this.request = req; + req.open("GET", "file_XHR_timeout.sjs"); + var me = this; + function handleEvent(e) { return me.handleEvent(e); }; + req.onerror = handleEvent; + req.onload = handleEvent; + req.onabort = handleEvent; + req.ontimeout = handleEvent; + + req.timeout = 2000; + var _this = this; + + function abortReq() { + req.abort(); + } + + if (!this.shouldAbort) { + self.setTimeout(function() { + try { + _this.noEventsFired(); + } + catch (e) { + ok(false, "Unexpected error: " + e); + TestCounter.testComplete(); + } + }, 5000); + } + else { + // Abort events can only be triggered on sent requests. + req.send(); + if (this.abortDelay == -1) { + abortReq(); + } + else { + self.setTimeout(abortReq, this.abortDelay); + } + } + }, + + /** + * Ensure that no events fired at all, especially not our timeout event. + */ + noEventsFired: function() { + ok(!this.hasFired, "No events should fire for an unsent, unaborted request"); + // We're done; if timeout hasn't fired by now, it never will. + TestCounter.testComplete(); + }, + + /** + * Get a message describing this test. + * + * @returns {String} The test description. + */ + getMessage: function() { + return "time to abort is " + this.abortDelay + ", timeout set at 2000"; + }, + + /** + * Check the event received, and if it's the right (and only) one we get. + * + * @param {DOMProgressEvent} evt An event of type "load" or "timeout". + */ + handleEvent: function(evt) { + if (this.hasFired) { + ok(false, "Only abort event should fire: " + this.getMessage()); + return; + } + this.hasFired = true; + + var expectedEvent = (this.abortDelay >= 2000) ? "timeout" : "abort"; + is(evt.type, expectedEvent, this.getMessage()); + TestCounter.testComplete(); + } +}; + +var SyncRequestSettingTimeoutAfterOpen = { + startXHR: function() { + var pass = false; + var req = new XMLHttpRequest(); + req.open("GET", "file_XHR_timeout.sjs", false); + try { + req.timeout = 1000; + } + catch (e) { + pass = true; + } + ok(pass, "Synchronous XHR must not allow a timeout to be set"); + TestCounter.testComplete(); + } +}; + +var SyncRequestSettingTimeoutBeforeOpen = { + startXHR: function() { + var pass = false; + var req = new XMLHttpRequest(); + req.timeout = 1000; + try { + req.open("GET", "file_XHR_timeout.sjs", false); + } + catch (e) { + pass = true; + } + ok(pass, "Synchronous XHR must not allow a timeout to be set"); + TestCounter.testComplete(); + } +}; + +var TestRequests = [ + // Simple timeouts. + new RequestTracker(true, "no time out scheduled, load fires normally", 0), + new RequestTracker(true, "load fires normally", 5000), + new RequestTracker(true, "timeout hit before load", 2000), + + // Timeouts reset after a certain delay. + new RequestTracker(true, "load fires normally with no timeout set, twice", 0, 2000, 0), + new RequestTracker(true, "load fires normally with same timeout set twice", 5000, 2000, 5000), + new RequestTracker(true, "timeout fires normally with same timeout set twice", 2000, 1000, 2000), + + new RequestTracker(true, "timeout disabled after initially set", 5000, 2000, 0), + new RequestTracker(true, "timeout overrides load after a delay", 5000, 1000, 2000), + new RequestTracker(true, "timeout enabled after initially disabled", 0, 2000, 5000), + + new RequestTracker(true, "timeout set to expiring value after load fires", 5000, 4000, 1000), + new RequestTracker(true, "timeout set to expired value before load fires", 5000, 2000, 1000), + new RequestTracker(true, "timeout set to non-expiring value after timeout fires", 1000, 2000, 5000), + + // Aborted requests. + new AbortedRequest(false), + new AbortedRequest(true, -1), + new AbortedRequest(true, 5000), +]; + +var MainThreadTestRequests = [ + new AbortedRequest(true, 0), + new AbortedRequest(true, 1000), + + // Synchronous requests. + SyncRequestSettingTimeoutAfterOpen, + SyncRequestSettingTimeoutBeforeOpen +]; + +var WorkerThreadTestRequests = [ + // Simple timeouts. + new RequestTracker(false, "no time out scheduled, load fires normally", 0), + new RequestTracker(false, "load fires normally", 5000), + new RequestTracker(false, "timeout hit before load", 2000), + + // Reset timeouts don't make much sense with a sync request ... +]; + +if (inWorker) { + TestRequests = TestRequests.concat(WorkerThreadTestRequests); +} else { + TestRequests = TestRequests.concat(MainThreadTestRequests); +} + +// This code controls moving from one test to another. +var TestCounter = { + testComplete: function() { + // Allow for the possibility there are other events coming. + self.setTimeout(function() { + TestCounter.next(); + }, 5000); + }, + + next: function() { + var test = TestRequests.shift(); + + if (test) { + test.startXHR(); + } + else { + message("done"); + } + } +}; + +self.addEventListener("message", function (event) { + if (event.data == "start") { + TestCounter.next(); + } +}); diff --git a/dom/xhr/tests/test_bug1300552.html b/dom/xhr/tests/test_bug1300552.html new file mode 100644 index 000000000..04f076f9d --- /dev/null +++ b/dom/xhr/tests/test_bug1300552.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1300552</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <script type="application/javascript"> + +var w = new Worker('worker_bug1300552.js'); +w.onmessage = function(e) { + if (e.data.type == 'info') { + info(e.data.msg); + } else if (e.data.type == 'check') { + ok(e.data.what, e.data.msg); + } else if (e.data.type == 'finish') { + SimpleTest.finish(); + } else { + ok(false, 'Something wrong happened'); + } +} + +SimpleTest.waitForExplicitFinish(); + + </script> +</body> +</html> diff --git a/dom/xhr/tests/test_html_in_xhr.html b/dom/xhr/tests/test_html_in_xhr.html new file mode 100644 index 000000000..ccfb71947 --- /dev/null +++ b/dom/xhr/tests/test_html_in_xhr.html @@ -0,0 +1,113 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=651072 +--> +<head> + <title>Test for Bug 651072</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload=runTest();> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=651072">Mozilla Bug 651072</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 651072 **/ +SimpleTest.waitForExplicitFinish(); + +var xhr = new XMLHttpRequest(); + +function runTest() { + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + ok(this.responseXML, "Should have gotten responseXML"); + is(this.responseXML.characterSet, "windows-1251", "Wrong character encoding"); + is(this.responseXML.documentElement.firstChild.data, " \u042E ", "Decoded using the wrong encoding."); + try { + this.responseText; + ok(false, "responseText access should have thrown."); + } catch (e) { + is(e.name, "InvalidStateError", "Should have thrown InvalidStateError."); + is(e.code, 11, "Should have thrown INVALID_STATE_ERR."); + } + is(this.responseXML.getElementsByTagName("div").length, 1, "There should be one div."); + ok(!this.responseXML.documentElement.hasAttribute("data-fail"), "Should not have a data-fail attribute."); + var scripts = this.responseXML.getElementsByTagName("script"); + is(scripts.length, 4, "Unexpected number of scripts."); + while (scripts.length) { + // These should not run when moved to another doc + document.body.appendChild(scripts[0]); + } + var s = document.createElement("script"); + s.src = "file_html_in_xhr.sjs?report=1"; + document.body.appendChild(s); + } + } + xhr.open("GET", "file_html_in_xhr.html", true); + xhr.responseType = "document"; + xhr.send(); +} + +function continueAfterReport() { + xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + is(this.responseText.indexOf("\u042E"), -1, "Honored meta in default mode."); + is(this.responseText.indexOf("\uFFFD"), 29, "Honored meta in default mode 2."); + is(this.responseXML, null, "responseXML should be null for HTML in the default mode"); + testNonParsingText(); + } + } + xhr.open("GET", "file_html_in_xhr2.html"); + xhr.send(); +} + +function testNonParsingText() { + xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + is(this.responseText.indexOf("\u042E"), -1, "Honored meta in text mode."); + is(this.responseText.indexOf("\uFFFD"), 29, "Honored meta in text mode 2."); + testChunkedText(); + } + } + xhr.open("GET", "file_html_in_xhr2.html"); + xhr.responseType = "text"; + xhr.send(); +} + +function testChunkedText() { + xhr = new XMLHttpRequest(); + xhr.onprogress = function() { + is(this.responseText.indexOf("\u042E"), -1, "Honored meta in chunked text mode."); + } + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + testSyncXHR(); + } + } + xhr.open("GET", "file_html_in_xhr2.html"); + xhr.responseType = "moz-chunked-text"; + xhr.send(); +} + +function testSyncXHR() { + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_html_in_xhr3.html", false); + xhr.send(); + is(xhr.responseText, "SUCCESS\n", "responseText should be ready by now"); + is(xhr.responseXML, null, "responseXML should be null in the sync case"); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> + diff --git a/dom/xhr/tests/test_relativeLoad.html b/dom/xhr/tests/test_relativeLoad.html new file mode 100644 index 000000000..fd471b894 --- /dev/null +++ b/dom/xhr/tests/test_relativeLoad.html @@ -0,0 +1,52 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> +<!-- +Tests of DOM Worker Threads relative load +--> +<head> + <title>Test for DOM Worker Threads</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + var index = -1; + + var urls = [ + "relativeLoad_worker.js", + "subdir/relativeLoad_sub_worker.js" + ]; + + function messageHandler(event) { + if (index >= 0) { + is(event.data, urls[index], "Bad url!"); + if (index == urls.length - 1) { + SimpleTest.finish(); + return; + } + } + + var worker = new Worker(urls[++index]); + worker.onmessage = messageHandler; + worker.onerror = function(event) { + ok(false, "Worker had an error: " + event.message); + SimpleTest.finish(); + }; + worker.postMessage("start"); + } + + messageHandler(); + + SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> + diff --git a/dom/xhr/tests/test_sync_xhr_document_write_with_iframe.html b/dom/xhr/tests/test_sync_xhr_document_write_with_iframe.html new file mode 100644 index 000000000..eaddc2feb --- /dev/null +++ b/dom/xhr/tests/test_sync_xhr_document_write_with_iframe.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug </title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script> +function runTest() { + let w = window.open('file_sync_xhr_document_write_with_iframe.html'); + addEventListener('message', evt => { + is(evt.data, 'DONE'); + w.close(); + SimpleTest.finish(); + }, { once: true }); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_sync_xhr_timer.xhtml b/dom/xhr/tests/test_sync_xhr_timer.xhtml new file mode 100644 index 000000000..ce6572362 --- /dev/null +++ b/dom/xhr/tests/test_sync_xhr_timer.xhtml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug </title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +<![CDATA[ + +var counter = 0; +var xhr; + +function syncXHR() { + xhr = new XMLHttpRequest(); + xhr.open("GET", window.location, false); + xhr.send(null); +} + +function increaseCounter() { + ++counter; + ok(counter <= 2, "Too many increaseCounter() calls!"); + if (counter == 2) { + ok(true, "increaseCounter() should be called twice!"); + SimpleTest.finish(); + } +} + +function runTest() { + setTimeout(syncXHR, 0); + setTimeout(increaseCounter, 0); + setTimeout(increaseCounter, 0); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + +]]> +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_sync_xhr_unload.html b/dom/xhr/tests/test_sync_xhr_unload.html new file mode 100644 index 000000000..b11ab1f75 --- /dev/null +++ b/dom/xhr/tests/test_sync_xhr_unload.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1307122</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="common_temporaryFileBlob.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +info("Creating the iframe..."); +var ifr = document.createElement('iframe'); + +ifr.addEventListener("load", function ifr_load1() { + info("Iframe loaded"); + + ifr.removeEventListener("load", ifr_load1); + ifr.src = "empty.html"; + + ifr.addEventListener("load", function ifr_load2() { + ok(true, "Test passed"); + SimpleTest.finish(); + }); + +}); + +ifr.src = "iframe_sync_xhr_unload.html"; +document.body.appendChild(ifr); + + </script> +</body> +</html> diff --git a/dom/xhr/tests/test_temporaryFileBlob.html b/dom/xhr/tests/test_temporaryFileBlob.html new file mode 100644 index 000000000..e4db56abd --- /dev/null +++ b/dom/xhr/tests/test_temporaryFileBlob.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1202006</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="common_temporaryFileBlob.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <script type="application/javascript"> + +var tests = [ + // from common_temporaryFileBlob.js: + test_simple, + test_reuse, + test_abort, + + test_worker, + test_worker_reuse, + test_worker_abort, +]; + +function next() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +SpecialPowers.pushPrefEnv({ "set" : [[ "dom.blob.memoryToTemporaryFile", 1 ]] }, + next); +SimpleTest.waitForExplicitFinish(); + + </script> +</body> +</html> diff --git a/dom/xhr/tests/test_worker_terminateSyncXHR.html b/dom/xhr/tests/test_worker_terminateSyncXHR.html new file mode 100644 index 000000000..11cea07d9 --- /dev/null +++ b/dom/xhr/tests/test_worker_terminateSyncXHR.html @@ -0,0 +1,45 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> +<!-- +Tests of DOM Worker Threads XHR(Bug 450452 ) +--> +<head> + <title>Test for DOM Worker Threads XHR (Bug 450452 )</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450452">DOM Worker Threads XHR (Bug 450452)</a> +<p id="display"></p> +<div id="content"> + <iframe id="iframe" src="worker_terminateSyncXHR_frame.html"></iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + var ifr = document.getElementById("iframe"); + + window.onmessage = function(event) { + if (event.data == "TERMINATE") { + ok(true, "Got TERMINATE"); + ifr.parentNode.removeChild(ifr); + SimpleTest.finish(); + } else { + ok(false, "Unexpected message: " + event.data); + } + } + + SimpleTest.waitForExplicitFinish(); + + window.onload = function() { + ifr.contentWindow.doStuff(); + } + +</script> +</pre> +</body> +</html> + diff --git a/dom/xhr/tests/test_worker_xhr.html b/dom/xhr/tests/test_worker_xhr.html new file mode 100644 index 000000000..0e875b7f4 --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr.html @@ -0,0 +1,73 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> +<!-- +Tests of DOM Worker Threads XHR(Bug 450452 ) +--> +<head> + <title>Test for DOM Worker Threads XHR (Bug 450452 )</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450452">DOM Worker Threads XHR (Bug 450452)</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + var worker = new Worker("xhr_worker.js"); + + var gotUploadLoad = false, gotLoadend = false; + + worker.onmessage = function(event) { + is(event.target, worker); + var args = event.data; + switch (args.type) { + case "progress": { + ok(parseInt(args.current) <= parseInt(args.total)); + } break; + case "error": { + ok(false, "XHR error: " + args.error); + } break; + case "upload.load": { + gotUploadLoad = true; + } break; + case "load": { + ok(gotUploadLoad, "Should have gotten upload load event"); + gotLoadend = true; + is(args.data, "A noisy noise annoys an oyster.", "correct data"); + document.getElementById("content").textContent = args.data; + } break; + case "loadend": { + ok(gotLoadend, "Should have gotten load."); + SimpleTest.finish(); + break; + } + default: { + ok(false, "Unexpected message"); + SimpleTest.finish(); + } + } + }; + + worker.onerror = function(event) { + is(event.target, worker); + ok(false, "Worker had an error:" + event.message); + SimpleTest.finish(); + } + + worker.postMessage("worker_testXHR.txt"); + + SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> + diff --git a/dom/xhr/tests/test_worker_xhr2.html b/dom/xhr/tests/test_worker_xhr2.html new file mode 100644 index 000000000..5f1816e45 --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr2.html @@ -0,0 +1,38 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> +<!-- +Tests of DOM Worker Threads XHR(Bug 450452 ) +--> +<head> + <title>Test for DOM Worker Threads XHR (Bug 450452 )</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450452">DOM Worker Threads XHR (Bug 450452)</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + var worker = new Worker("xhr2_worker.js"); + + worker.onmessage = function(event) { + is(event.data, "done", "Got correct result"); + SimpleTest.finish(); + } + worker.postMessage("worker_testXHR.txt"); + + SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> + diff --git a/dom/xhr/tests/test_worker_xhrAbort.html b/dom/xhr/tests/test_worker_xhrAbort.html new file mode 100644 index 000000000..0f4b93c5a --- /dev/null +++ b/dom/xhr/tests/test_worker_xhrAbort.html @@ -0,0 +1,44 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> +<!-- +Tests of DOM Worker Threads XHR(Bug 450452 ) +--> +<head> + <title>Test for DOM Worker Threads XHR (Bug 450452 )</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450452">DOM Worker Threads XHR (Bug 450452)</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script language="javascript" src="xhrAbort_worker.js"></script> +<script class="testbody" language="javascript"> + + function postMessage(data) { + dump(data.toString() + "\n"); + + var worker = new Worker("xhrAbort_worker.js"); + + worker.onmessage = function(event) { + is (data.toString(), event.data.toString(), "Got different results!"); + SimpleTest.finish(); + }; + + worker.postMessage("start"); + } + + runTest(); + + SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_worker_xhr_3rdparty.html b/dom/xhr/tests/test_worker_xhr_3rdparty.html new file mode 100644 index 000000000..46951012a --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_3rdparty.html @@ -0,0 +1,74 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> +<!-- +Tests of DOM Worker Threads XHR(Bug 450452 ) +--> +<head> + <title>Test for DOM Worker Threads XHR (Bug 450452 )</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450452">DOM Worker Threads XHR (Bug 450452)</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + var worker = new Worker("xhr_worker.js"); + + var gotUploadLoad = false, gotLoadend = false; + + worker.onmessage = function(event) { + is(event.target, worker); + var args = event.data; + switch (args.type) { + case "progress": { + ok(parseInt(args.current) <= parseInt(args.total)); + } break; + case "error": { + ok(false, "XHR error: " + args.error); + } break; + case "upload.load": { + gotUploadLoad = true; + } break; + case "load": { + ok(gotUploadLoad, "Should have gotten upload load event"); + gotLoadend = true; + is(args.data, "a=cookie_is_set", "correct data"); + document.getElementById("content").textContent = args.data; + } break; + case "loadend": { + ok(gotLoadend, "Should have gotten load."); + SimpleTest.finish(); + break; + } + default: { + ok(false, "Unexpected message"); + SimpleTest.finish(); + } + } + }; + + worker.onerror = function(event) { + is(event.target, worker); + ok(false, "Worker had an error:" + event.message); + SimpleTest.finish(); + } + + document.cookie = "a=cookie_is_set"; + SpecialPowers.pushPrefEnv({ set: [[ "network.cookie.cookieBehavior", 1 ]] }, + () => worker.postMessage("worker_file_getcookie.sjs")); + + SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_worker_xhr_cors_redirect.html b/dom/xhr/tests/test_worker_xhr_cors_redirect.html new file mode 100644 index 000000000..40967d5d8 --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_cors_redirect.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1206121</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + +"use strict"; + +var worker = new Worker("worker_xhr_cors_redirect.js"); +worker.onmessage = function(e) { + is(e.data, 200, "We want to read 200 here."); + runTests(); +}; + +var tests = [ 'http://example.com/tests/dom/xhr/tests/worker_xhr_cors_redirect.sjs', + 'http://example.com/tests/dom/xhr/tests/worker_xhr_cors_redirect.sjs?redirect', + 'worker_xhr_cors_redirect.sjs?redirect' ]; +function runTests() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + worker.postMessage(tests.shift()); +} + +SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body onload="runTests()"> +</body> +</html> diff --git a/dom/xhr/tests/test_worker_xhr_headers.html b/dom/xhr/tests/test_worker_xhr_headers.html new file mode 100644 index 000000000..1416ababd --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_headers.html @@ -0,0 +1,86 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> + <head> + <title>Test for XHR Headers</title> + <script src="/tests/SimpleTest/SimpleTest.js"> + </script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> + </head> + <body> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + <script class="testbody"> +"use strict"; + +SimpleTest.waitForExplicitFinish(); + +var path = + location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); +var filenamePrefix = "worker_xhr_headers_"; +var serverFilename = filenamePrefix + "server.sjs"; +var workerFilename = filenamePrefix + "worker.js"; +var otherHost = "example.com"; + +info("Informing server about the current host"); + +var xhr = new XMLHttpRequest(); +xhr.open("POST", path + serverFilename); +xhr.setRequestHeader("options-host", otherHost); +xhr.setRequestHeader("empty", ""); +xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + info("Launching worker"); + + var worker = new Worker(path + workerFilename); + worker.postMessage("http://" + otherHost + path + serverFilename); + + worker.onmessage = function(event) { + ok(event.data.response === "", "Worker responded, saw no response"); + + var loopCount = 0; + + function checkServer() { + var xhr2 = new XMLHttpRequest(); + xhr2.open("GET", path + serverFilename); + xhr2.onreadystatechange = function() { + if (xhr2.readyState == 4) { + if (xhr2.responseText) { + is(xhr2.responseText, + "Success: expected OPTIONS request with '" + + event.data.header + "' header", + "Server saw expected requests"); + SimpleTest.finish(); + } else if (++loopCount < 30) { + setTimeout(checkServer, 1000); + } else { + ok(false, "Server never saw any requests"); + SimpleTest.finish(); + } + } + }; + + info("Checking server status (" + loopCount + ")"); + xhr2.send(); + } + + checkServer(); + }; + + worker.onerror = function(event) { + ok(false, "Worker had an error: '" + event.message + "'"); + event.preventDefault(); + SimpleTest.finish(); + }; + } +}; +xhr.send(); + + </script> + </pre> + </body> +</html> diff --git a/dom/xhr/tests/test_worker_xhr_implicit_cancel.html b/dom/xhr/tests/test_worker_xhr_implicit_cancel.html new file mode 100644 index 000000000..a9efb14b9 --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_implicit_cancel.html @@ -0,0 +1,44 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> +<!-- +Tests of DOM Worker Threads XHR(Bug 450452 ) +--> +<head> + <title>Test for DOM Worker Threads XHR (Bug 450452 )</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450452">DOM Worker Threads XHR (Bug 450452)</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + var worker = new Worker("xhr_implicit_cancel_worker.js"); + + worker.onmessage = function(event) { + is(event.target, worker, "Expected event target for message"); + ok(true, "Worker didn't have an error"); + SimpleTest.finish(); + }; + + worker.onerror = function(event) { + is(event.target, worker, "Expected event target for error"); + ok(false, "Worker had an error:" + event.message); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> + diff --git a/dom/xhr/tests/test_worker_xhr_parameters.html b/dom/xhr/tests/test_worker_xhr_parameters.html new file mode 100644 index 000000000..ae880aabb --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_parameters.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Test for XMLHttpRequest with system privileges</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +function message(event) { + if (event.data.test == 'ok') + ok(event.data.a, event.data.event); + else if(event.data.test == 'is') + is(event.data.a, event.data.b, event.data.event); + else if(event.data.test == 'finish') { + run(); + } +}; + +function test1() { + var worker = new Worker("test_worker_xhr_parameters.js"); + worker.onmessage = message; + + // Run the tests once without API privileges... + worker.postMessage(false); +} + +function test2() { + // ...and once with privileges. + SpecialPowers.pushPermissions([{type: "systemXHR", allow: true, context: document}], + function () { + var worker = new Worker("test_worker_xhr_parameters.js"); + worker.onmessage = message; + worker.postMessage(true); + } + ); +} + +var tests = [ test1, test2 ]; +function run() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var func = tests.shift(); + func(); +} + +SimpleTest.waitForExplicitFinish(); +run(); + +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_worker_xhr_parameters.js b/dom/xhr/tests/test_worker_xhr_parameters.js new file mode 100644 index 000000000..80db35a43 --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_parameters.js @@ -0,0 +1,75 @@ +function ok(what, msg) { + postMessage({ event: msg, test: 'ok', a: what }); +} + +function is(a, b, msg) { + postMessage({ event: msg, test: 'is', a: a, b: b }); +} + +// This is a copy of dom/xhr/tests/test_XHR_parameters.js +var validParameters = [ + undefined, + null, + {}, + {mozSystem: ""}, + {mozSystem: 0}, + {mozAnon: 1}, + {mozAnon: []}, + {get mozAnon() { return true; }}, + 0, + 7, + Math.PI, + "string", + true, + false, +]; + +var invalidParameters = [ + {get mozSystem() { throw "Bla"; } }, +]; + + +function testParameters(havePrivileges) { + + function testValidParameter(value) { + var xhr; + try { + xhr = new XMLHttpRequest(value); + } catch (ex) { + ok(false, "Got unexpected exception: " + ex); + return; + } + ok(!!xhr, "passed " + JSON.stringify(value)); + + // If the page doesnt have privileges to create a system or anon XHR, + // these flags will always be false no matter what is passed. + var expectedAnon = false; + var expectedSystem = false; + if (havePrivileges) { + expectedAnon = Boolean(value && value.mozAnon); + expectedSystem = Boolean(value && value.mozSystem); + } + is(xhr.mozAnon, expectedAnon, "testing mozAnon"); + is(xhr.mozSystem, expectedSystem, "testing mozSystem"); + } + + + function testInvalidParameter(value) { + try { + new XMLHttpRequest(value); + ok(false, "invalid parameter did not cause exception: " + + JSON.stringify(value)); + } catch (ex) { + ok(true, "invalid parameter raised exception as expected: " + + JSON.stringify(ex)); + } + } + + validParameters.forEach(testValidParameter); + invalidParameters.forEach(testInvalidParameter); +} + +self.onmessage = function onmessage(event) { + testParameters(event.data); + postMessage({test: "finish"}); +}; diff --git a/dom/xhr/tests/test_worker_xhr_responseURL.html b/dom/xhr/tests/test_worker_xhr_responseURL.html new file mode 100644 index 000000000..424d0b95d --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_responseURL.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=998076 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 998076</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + +/** Test for Bug 998076 **/ +"use strict"; + +var worker = new Worker("../../../dom/xhr/tests/file_XHRResponseURL.js"); + +var requestObserver = { + observe: function (aSubject, aTopic, aData) { + worker.postMessage("request"); + } +}; + +worker.addEventListener("message", function (aEvent) { + var data = aEvent.data; + if (data == "done") { + SimpleTest.finish(); + return; + } + if (data == "start") { + return; + } + if (data.type == "is") { + SimpleTest.is(data.actual, data.expected, data.message); + worker.postMessage("pong"); + return; + } + if (data.type == "ok") { + SimpleTest.ok(data.bool, data.message); + worker.postMessage("pong"); + return; + } + if (data.type == "info") { + SimpleTest.info(data.message); + worker.postMessage("pong"); + return; + } + if (data.type === "redirect_test") { + if (data.status === "start") { + SpecialPowers.addObserver(requestObserver, "specialpowers-http-notify-request", false); + return; + } + if (data.status === "end") { + SpecialPowers.removeObserver(requestObserver, "specialpowers-http-notify-request"); + return; + } + } +}); + +function runTests() { + SimpleTest.waitForExplicitFinish(); + worker.postMessage("start"); +} + + </script> +</head> +<body onload="runTests()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=998076">Mozilla Bug 998076</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_worker_xhr_system.html b/dom/xhr/tests/test_worker_xhr_system.html new file mode 100644 index 000000000..6de0016e2 --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_system.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Test for XMLHttpRequest with system privileges</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +function message(event) { + if (event.data.test == 'ok') + ok(event.data.a, event.data.event); + else if(event.data.test == 'is') + is(event.data.a, event.data.b, event.data.event); + else if(event.data.test == 'finish') { + run(); + } +}; + +function test1() { + var worker = new Worker("test_worker_xhr_system.js"); + worker.onmessage = message; + worker.postMessage(true); +} + +var tests = [ test1 ]; +function run() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var func = tests.shift(); + func(); +} + +SimpleTest.waitForExplicitFinish(); + +SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], run); + +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_worker_xhr_system.js b/dom/xhr/tests/test_worker_xhr_system.js new file mode 100644 index 000000000..5ad63225c --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_system.js @@ -0,0 +1,30 @@ +function ok(what, msg) { + postMessage({ event: msg, test: 'ok', a: what }); +} + +function is(a, b, msg) { + postMessage({ event: msg, test: 'is', a: a, b: b }); +} + +self.onmessage = function onmessage(event) { + + // An XHR with system privileges will be able to do cross-site calls. + + const TEST_URL = "http://example.com/tests/dom/xhr/tests/test_XHR_system.html"; + is(location.hostname, "mochi.test", "hostname should be mochi.test"); + + var xhr = new XMLHttpRequest({mozSystem: true}); + is(xhr.mozSystem, true, ".mozSystem == true"); + xhr.open("GET", TEST_URL); + xhr.onload = function onload() { + is(xhr.status, 200); + ok(xhr.responseText != null); + ok(xhr.responseText.length); + postMessage({test: "finish"}); + }; + xhr.onerror = function onerror() { + ok(false, "Got an error event!"); + postMessage({test: "finish"}); + } + xhr.send(); +}; diff --git a/dom/xhr/tests/test_worker_xhr_timeout.html b/dom/xhr/tests/test_worker_xhr_timeout.html new file mode 100644 index 000000000..d9bb6a7ae --- /dev/null +++ b/dom/xhr/tests/test_worker_xhr_timeout.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=498998 +--> +<head> + <title>Test for Bug 498998</title> + <script type="application/javascript" + src="/MochiKit/MochiKit.js"></script> + <script type="application/javascript" + src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" + type="text/css" + href="/tests/SimpleTest/test.css"> +</head> +<body> + +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=498998" + >Mozilla Bug 498998 (Worker XMLHttpRequest timeout)</a> +<p id="display"></p> +<div id="content"> + This test takes over 1 minute to run, probably over 2 minutes. +</div> +<pre id="test"> +<script type="text/javascript"> + var worker = new Worker("../../../dom/xhr/tests/test_XHR_timeout.js"); + + worker.addEventListener("message", function (event) { + if (event.data == "done") { + SimpleTest.finish(); + return; + } + if (event.data == "start") { + return; + } + if (event.data.type == "is") { + SimpleTest.is(event.data.got, event.data.expected, event.data.msg); + return; + } + if (event.data.type == "ok") { + SimpleTest.ok(event.data.bool, event.data.msg); + return; + } + }); + // Final test harness setup and launch. + (function() { + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestLongerTimeout(20); + var msg = "This test will take approximately " + (20 * 10) + msg += " seconds to complete, at most."; + document.getElementById("content").firstChild.nodeValue = msg; + worker.postMessage("start"); + })(); +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_xhr_abort_after_load.html b/dom/xhr/tests/test_xhr_abort_after_load.html new file mode 100644 index 000000000..780c11253 --- /dev/null +++ b/dom/xhr/tests/test_xhr_abort_after_load.html @@ -0,0 +1,96 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test bug 482935</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href=" /tests/SimpleTest/test.css" /> +</head> +<body onload="onWindowLoad()"> +<script class="testbody" type="text/javascript">"use strict"; +SimpleTest.waitForExplicitFinish(); + +var url = "file_XHR_pass1.xml"; + +function onWindowLoad() { + runTest(); +} + +function runTest() { + var testFunctions = [ + startTest1, + startTest2, + startTest3, + ]; + + function nextTest() { + if (testFunctions.length == 0) { + SimpleTest.finish(); + return; + } + (testFunctions.shift())(); + } + + nextTest(); + + var xhr; + function startTest1() { + xhr = new XMLHttpRequest(); + xhr.onload = onLoad1; + xhr.open("GET", url); + xhr.send(); + } + + function onLoad1() { + is(xhr.readyState, xhr.DONE, "readyState should be DONE"); + xhr.onabort = onAbort1; + xhr.abort(); + + function onAbort1(e) { + ok(false, e.type + " event should not be fired!"); + } + + is(xhr.readyState, xhr.UNSENT, "readyState should be UNSENT"); + nextTest(); + } + + function startTest2() { + xhr = new XMLHttpRequest(); + xhr.onloadstart = onAfterSend; + xhr.open("GET", url); + xhr.send(); + } + + function startTest3() { + xhr = new XMLHttpRequest(); + xhr.open("GET", url); + xhr.send(); + onAfterSend(); + } + + function onAfterSend() { + is(xhr.readyState, xhr.OPENED, "readyState should be OPENED"); + var sent = false; + try { + xhr.send(); + } catch (e) { + sent = true; + } + ok(sent, "send() flag should be set"); + var aborted = false; + xhr.onabort = onAbort2; + xhr.abort(); + + function onAbort2() { + is(xhr.readyState, xhr.DONE, "readyState should be DONE"); + aborted = true; + } + + ok(aborted, "abort event should be fired"); + is(xhr.readyState, xhr.UNSENT, "readyState should be UNSENT"); + nextTest(); + } +} + +</script> +</body> +</html> diff --git a/dom/xhr/tests/test_xhr_forbidden_headers.html b/dom/xhr/tests/test_xhr_forbidden_headers.html new file mode 100644 index 000000000..fc076731e --- /dev/null +++ b/dom/xhr/tests/test_xhr_forbidden_headers.html @@ -0,0 +1,96 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=308484 +--> +<head> + <title>Test for Bug 308484</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=308484">Mozilla Bug 308484</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 308484 **/ + +var headers = [ + "aCCept-chaRset", + "acCePt-eNcoDing", + "aCcEsS-cOnTrOl-ReQuEsT-mEtHoD", + "aCcEsS-cOnTrOl-ReQuEsT-hEaDeRs", + "coNnEctIon", + "coNtEnt-LEngth", + "CoOKIe", + "cOOkiE2", + "DATE", + "dNT", + "exPeCt", + "hOSt", + "keep-alive", + "oRiGiN", + "reFERer", + "te", + "trAiLer", + "trANsfEr-eNcoDiNg", + "uPGraDe", + "viA", + "pRoxy-", + "sEc-", + "proxy-fOobar", + "sec-bAZbOx" +]; +var i, request; + +function startTest() { + // Try setting headers in unprivileged context + request = new XMLHttpRequest(); + request.open("GET", window.location.href); + for (i = 0; i < headers.length; i++) + request.setRequestHeader(headers[i], "test" + i); + request.send(); // headers aren't set on the channel until send() + + // Read out headers + var channel = SpecialPowers.wrap(request).channel.QueryInterface(SpecialPowers.Ci.nsIHttpChannel); + for (i = 0; i < headers.length; i++) { + // Retrieving Content-Length will throw an exception + var value = null; + try { + value = channel.getRequestHeader(headers[i]); + } + catch(e) {} + + isnot(value, "test" + i, "Setting " + headers[i] + " header in unprivileged context"); + } + + // Try setting headers in privileged context + request = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + request.open("GET", window.location.href); + for (i = 0; i < headers.length; i++) + request.setRequestHeader(headers[i], "test" + i); + request.send(); // headers aren't set on the channel until send() + + // Read out headers + var channel = SpecialPowers.wrap(request).channel.QueryInterface(SpecialPowers.Ci.nsIHttpChannel); + for (i = 0; i < headers.length; i++) { + var value = channel.getRequestHeader(headers[i]); + is(value, "test" + i, "Setting " + headers[i] + " header in privileged context"); + } + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], startTest); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_xhr_overridemimetype_throws_on_invalid_state.html b/dom/xhr/tests/test_xhr_overridemimetype_throws_on_invalid_state.html new file mode 100644 index 000000000..bdbbf1591 --- /dev/null +++ b/dom/xhr/tests/test_xhr_overridemimetype_throws_on_invalid_state.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test bug 482935</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href=" /tests/SimpleTest/test.css" /> +</head> +<body onload="onWindowLoad()"> +<script class="testbody" type="text/javascript">"use strict"; +SimpleTest.waitForExplicitFinish(); + +var url = "file_XHR_pass1.xml"; + +function onWindowLoad() { + runTest(); +} + +function runTest() { + var testFunctions = [ + function() { testOverMimeTypeThrowsDuringReadyState(3, "application/xml"); }, + function() { testOverMimeTypeThrowsDuringReadyState(3, "application/xml;charset=Shift-JIS"); }, + function() { testOverMimeTypeThrowsDuringReadyState(4, "application/xml"); }, + function() { testOverMimeTypeThrowsDuringReadyState(4, "application/xml;charset=Shift-JIS"); }, + ]; + + function nextTest() { + if (testFunctions.length == 0) { + SimpleTest.finish(); + return; + } + (testFunctions.shift())(); + } + + nextTest(); + + function testOverMimeTypeThrowsDuringReadyState(readyState, mimeType) { + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function() { + if (xhr.readyState === readyState) { + try { + xhr.overrideMimeType(mimeType); + ok(false, "No exception thrown, but expected InvalidStateError" + + " for readyState=" + readyState + ", mimeType=" + mimeType); + } catch(exc) { + is(exc.name, "InvalidStateError", "Expected InvalidStateError, got " + exc.name + + " for readyState=" + readyState + ", mimeType=" + mimeType); + } + } + if (xhr.readyState === 4) { + is(xhr.responseXML, null, "responseXML was not null" + + " for readyState=" + readyState + ", mimeType=" + mimeType); + nextTest(); + } + } + xhr.open("GET", url); + xhr.send(); + } +} +</script> +</body> +</html> diff --git a/dom/xhr/tests/test_xhr_progressevents.html b/dom/xhr/tests/test_xhr_progressevents.html new file mode 100644 index 000000000..f22927daf --- /dev/null +++ b/dom/xhr/tests/test_xhr_progressevents.html @@ -0,0 +1,333 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for XMLHttpRequest Progress Events</title> + <script type="text/javascript" src="/MochiKit/packed.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="gen.next();"> +<pre id=l></pre> +<script type="application/javascript;version=1.7"> +SimpleTest.waitForExplicitFinish(); + +var gen = runTests(); + +function log(s) { + // Uncomment these to get debugging information + /* + document.getElementById("l").textContent += s + "\n"; + dump(s + "\n"); + */ +} + +function getEvent(e) { + log("got event: " + e.type + " (" + e.target.readyState + ")"); + gen.send(e); +} + +function startsWith(a, b) { + return a.substr(0, b.length) === b; +} + +function updateProgress(e, data, testName) { + var test = " while running " + testName; + is(e.type, "progress", "event type" + test); + + let response; + if (data.nodata) { + is(e.target.response, null, "response should be null" + test); + response = null; + } + else if (data.text) { + is(typeof e.target.response, "string", "response should be a string" + test); + response = e.target.response; + } + else if (data.blob) { + ok(e.target.response instanceof Blob, "response should be a Blob" + test); + response = e.target.response; + } + else { + ok(e.target.response instanceof ArrayBuffer, "response should be an ArrayBuffer" + test); + response = bufferToString(e.target.response); + } + is(e.target.response, e.target.response, "reflexivity should hold" + test); + + if (!data.nodata && !data.encoded) { + if (data.blob) { + is(e.loaded, response.size, "event.loaded matches response size" + test); + } + else if (!data.chunked) { + is(e.loaded, response.length, "event.loaded matches response size" + test); + } + else { + is(e.loaded - data.receivedBytes, response.length, + "event.loaded grew by response size" + test); + } + } + ok(e.loaded > data.receivedBytes, "event.loaded increased" + test); + ok(e.loaded - data.receivedBytes <= data.pendingBytes, + "event.loaded didn't increase too much" + test); + + if (!data.nodata && !data.blob) { + var newData; + ok(startsWith(response, data.receivedResult), + "response strictly grew" + test); + newData = response.substr(data.receivedResult.length); + + if (!data.encoded) { + ok(newData.length > 0, "sanity check for progress" + test); + } + ok(startsWith(data.pendingResult, newData), "new data matches expected" + test); + } + + is(e.lengthComputable, "total" in data, "lengthComputable" + test); + if ("total" in data) { + is(e.total, data.total, "total" + test); + } + + if (!data.nodata && !data.blob) { + data.pendingResult = data.pendingResult.substr(newData.length); + } + data.pendingBytes -= e.loaded - data.receivedBytes; + data.receivedResult = response; + data.receivedBytes = e.loaded; +} + +function sendData(s) { + var xhr = new XMLHttpRequest(); + xhr.open("POST", "progressserver.sjs?send"); + // The Blob constructor encodes String elements as UTF-8; + // for straight bytes, manually convert to ArrayBuffer first + var buffer = new Uint8Array(s.length); + for (var i = 0; i < s.length; ++i) { + buffer[i] = s.charCodeAt(i) & 0xff; + }; + xhr.send(new Blob([buffer])); +} + +function closeConn() { + log("in closeConn"); + var xhr = new XMLHttpRequest(); + xhr.open("POST", "progressserver.sjs?close"); + xhr.send(); + return xhr; +} + +var longString = "long"; +while(longString.length < 65536) + longString += longString; + +function utf8encode(s) { + return unescape(encodeURIComponent(s)); +} + +function bufferToString(buffer) { + return String.fromCharCode.apply(String, new Uint8Array(buffer)); +} + +function runTests() { + var xhr = new XMLHttpRequest(); + xhr.onprogress = xhr.onload = xhr.onerror = xhr.onreadystatechange = xhr.onloadend = getEvent; + + var responseTypes = [{ type: "text", text: true }, + { type: "arraybuffer", text: false, nodata: true }, + { type: "blob", text: false, nodata: true, blob: true }, + { type: "moz-blob", text: false, nodata: false, blob: true }, + { type: "document", text: true, nodata: true }, + { type: "json", text: true, nodata: true }, + { type: "", text: true }, + { type: "moz-chunked-text", text: true, chunked: true }, + { type: "moz-chunked-arraybuffer", text: false, chunked: true }, + ]; + var responseType; + var fileExpectedResult = ""; + for (var i = 0; i < 65536; i++) { + fileExpectedResult += String.fromCharCode(i & 255); + } + while (responseType = responseTypes.shift()) { + let tests = [{ open: "Content-Type=text/plain", name: "simple test" }, + { data: "hello world" }, + { data: "\u0000\u0001\u0002\u0003" }, + { data: longString }, + { data: "x" }, + { close: true }, + { open: "Content-Type=text/plain&Content-Length=20", name: "with length", total: 20 }, + // 5 bytes from the "ready" in the open step + { data: "abcde" }, + { data: "0123456789" }, + { close: true }, + { open: "Content-Type=application/xml", name: "without length, as xml" }, + { data: "<out>" }, + { data: "text" }, + { data: "</foo>invalid" }, + { close: true }, + { open: "Content-Type=text/plain;charset%3dutf-8", name: "utf8 data", encoded: true }, + { data: utf8encode("räksmörgÃ¥s"), utf16: "räksmörgÃ¥s" }, + { data: utf8encode("Ã…").substr(0,1), utf16: "" }, + { data: utf8encode("Ã…").substr(1), utf16: "Ã…" }, + { data: utf8encode("aöb").substr(0,2), utf16: "a" }, + { data: utf8encode("aöb").substr(2), utf16: "öb" }, + { data: utf8encode("a\u867Eb").substr(0,3), utf16: "a" }, + { data: utf8encode("a\u867Eb").substr(3,1), utf16: "\u867E" }, + { data: utf8encode("a\u867Eb").substr(4), utf16: "b" }, + { close: true }, + ]; + if (responseType.blob) { + tests.push({ file: "file_XHR_binary2.bin", name: "cacheable data", total: 65536 }, + { close: true }, + { file: "file_XHR_binary2.bin", name: "cached data", total: 65536 }, + { close: true }); + } + let testState = { index: 0 }; + + for (let i = 0; i < tests.length; ++i) { + let test = tests[i]; + testState.index++; + if ("open" in test || "file" in test) { + log("opening " + testState.name); + testState = { name: test.name + " for " + responseType.type, + index: 0, + pendingResult: "ready", + pendingBytes: 5, + receivedResult: "", + receivedBytes: 0, + total: test.total, + encoded: test.encoded, + nodata: responseType.nodata, + chunked: responseType.chunked, + text: responseType.text, + blob: responseType.blob, + file: test.file }; + + xhr.onreadystatechange = null; + if (testState.file) + xhr.open("GET", test.file); + else + xhr.open("POST", "progressserver.sjs?open&" + test.open); + xhr.responseType = responseType.type; + xhr.send("ready"); + xhr.onreadystatechange = getEvent; + + let e = yield undefined; + is(e.type, "readystatechange", "should readystate to headers-received starting " + testState.name); + is(xhr.readyState, xhr.HEADERS_RECEIVED, "should be in state HEADERS_RECEIVED starting " + testState.name); + + e = yield undefined; + is(e.type, "readystatechange", "should readystate to loading starting " + testState.name); + is(xhr.readyState, xhr.LOADING, "should be in state LOADING starting " + testState.name); + if (typeof testState.total == "undefined") + delete testState.total; + } + if ("file" in test) { + testState.pendingBytes = testState.total; + testState.pendingResult = fileExpectedResult; + } + if ("close" in test) { + log("closing"); + let xhrClose; + if (!testState.file) + xhrClose = closeConn(); + + e = yield undefined; + is(e.type, "readystatechange", "should readystate to done closing " + testState.name); + is(xhr.readyState, xhr.DONE, "should be in state DONE closing " + testState.name); + log("readystate to 4"); + + if (responseType.chunked) { + xhr.responseType; + is(xhr.response, null, "chunked data has null response for " + testState.name); + } + + e = yield undefined; + is(e.type, "load", "should fire load closing " + testState.name); + is(e.lengthComputable, e.total != 0, "length should " + (e.total == 0 ? "not " : "") + "be computable during load closing " + testState.name); + log("got load"); + + if (responseType.chunked) { + is(xhr.response, null, "chunked data has null response for " + testState.name); + } + + e = yield undefined; + is(e.type, "loadend", "should fire loadend closing " + testState.name); + is(e.lengthComputable, e.total != 0, "length should " + (e.total == 0 ? "not " : "") + "be computable during loadend closing " + testState.name); + log("got loadend"); + + // if we closed the connection using an explicit request, make sure that goes through before + // running the next test in order to avoid reordered requests from closing the wrong + // connection. + if (xhrClose && xhrClose.readyState != xhrClose.DONE) { + log("wait for closeConn to finish"); + xhrClose.onloadend = getEvent; + yield undefined; + is(xhrClose.readyState, xhrClose.DONE, "closeConn finished"); + } + + if (responseType.chunked) { + is(xhr.response, null, "chunked data has null response for " + testState.name); + } + + if (!testState.nodata && !responseType.blob || responseType.chunked) { + // This branch intentionally left blank + // Under these conditions we check the response during updateProgress + } + else if (responseType.type === "arraybuffer") { + is(bufferToString(xhr.response), testState.pendingResult, + "full response for " + testState.name); + } + else if (responseType.blob) { + let reader = new FileReader; + reader.readAsBinaryString(xhr.response); + reader.onloadend = getEvent; + yield undefined; + + is(reader.result, testState.pendingResult, + "full response in blob for " + testState.name); + } + + testState.name = ""; + } + if ("data" in test) { + log("sending"); + if (responseType.text) { + testState.pendingResult += "utf16" in test ? test.utf16 : test.data; + } + else { + testState.pendingResult += test.data; + } + testState.pendingBytes = test.data.length; + sendData(test.data); + } + + while(testState.pendingBytes) { + log("waiting for more bytes: " + testState.pendingBytes); + e = yield undefined; + // Readystate can fire several times between each progress event. + if (e.type === "readystatechange") + continue; + + updateProgress(e, testState, "data for " + testState.name + "[" + testState.index + "]"); + if (responseType.chunked) { + testState.receivedResult = ""; + } + } + + if (!testState.nodata && !testState.blob) { + is(testState.pendingResult, "", + "should have consumed the expected result"); + } + + log("done with this test"); + } + + is(testState.name, "", "forgot to close last test"); + } + + SimpleTest.finish(); + yield undefined; +} + +</script> + +</body> +</html> diff --git a/dom/xhr/tests/test_xhr_send.html b/dom/xhr/tests/test_xhr_send.html new file mode 100644 index 000000000..6633dcb15 --- /dev/null +++ b/dom/xhr/tests/test_xhr_send.html @@ -0,0 +1,83 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1096263 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1096263</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1096263 **/ + +SimpleTest.waitForExplicitFinish(); + +function simpleGetTest() { + var x = new XMLHttpRequest(); + x.open("GET", "echo.sjs"); + x.onload = function() { + ok(true, "Should have processed GET"); + simplePostTest(); + } + x.send({}); +} + +function simplePostTest() { + var x = new XMLHttpRequest(); + x.open("POST", "echo.sjs"); + x.onload = function() { + is(x.responseText, "somedata", "Should have processed POST"); + undefinedPostTest(); + } + x.send({toString: function() { return "somedata"; }}); +} + +function undefinedPostTest() { + var x = new XMLHttpRequest(); + x.open("POST", "echo.sjs"); + x.onload = function() { + is(x.responseText, "undefined", "Should have processed POST"); + nullPostTest(); + } + x.send({toString: function() { return undefined; }}); +} + +function nullPostTest() { + var x = new XMLHttpRequest(); + x.open("POST", "echo.sjs"); + x.onload = function() { + is(x.responseText, "null", "Should have processed POST"); + testExceptionInToString(); + } + x.send({toString: function() { return null; }}); +} + +function testExceptionInToString() { + var x = new XMLHttpRequest(); + x.open("GET", "echo.sjs"); + x.onload = function() { + ok(false); + SimpleTest.finish(); + } + try { + x.send({toString: function() { throw "dummy"; }}); + } catch(ex) { + is(ex, "dummy"); + SimpleTest.finish(); + } +} + + </script> +</head> +<body onload="simpleGetTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1096263">Mozilla Bug 1096263</a> +<p id="display"></p> +<div id="content"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_xhr_send_readystate.html b/dom/xhr/tests/test_xhr_send_readystate.html new file mode 100644 index 000000000..1c86681de --- /dev/null +++ b/dom/xhr/tests/test_xhr_send_readystate.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=814064 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 814064</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=814064">Mozilla Bug 814064</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 814064 **/ +var xhr = new XMLHttpRequest(); +var firings = 0; +function readyStateHandler() { + is(xhr.readyState, XMLHttpRequest.OPENED, "Should be in OPENED state"); + ++firings; +} +xhr.onreadystatechange = readyStateHandler; +xhr.open("GET", ""); +is(firings, 1, "Should have fired the readystatechange handler"); +xhr.send(); +is(firings, 1, "Should not have fired the readystatechange handler"); +xhr.onreadystatechange = null; +xhr.abort(); +is(firings, 1, "Should not have fired the handler no-longer-registered handler"); +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/test_xhr_withCredentials.html b/dom/xhr/tests/test_xhr_withCredentials.html new file mode 100644 index 000000000..71d7dcccf --- /dev/null +++ b/dom/xhr/tests/test_xhr_withCredentials.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=814050 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 814050</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=814050">Mozilla Bug 814050</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 814050, but modified now that the spec has changed **/ +var xhr = new XMLHttpRequest(); +xhr.open("GET", "", false); +xhr.withCredentials = true; +ok(true, "Should not throw on withCredentials sets for sync XHR"); + +var xhr = new XMLHttpRequest(); +xhr.open("GET", "", true); +xhr.withCredentials = true; +ok(true, "Should not throw on withCredentials sets for async XHR"); + +</script> +</pre> +</body> +</html> diff --git a/dom/xhr/tests/worker_bug1300552.js b/dom/xhr/tests/worker_bug1300552.js new file mode 100644 index 000000000..fbc58b880 --- /dev/null +++ b/dom/xhr/tests/worker_bug1300552.js @@ -0,0 +1,33 @@ +function info(msg) { + postMessage({type: 'info', msg: msg}); +} + +function ok(a, msg) { + postMessage({type: 'check', what: !!a, msg: msg}); +} + +function finish() { + postMessage({type: 'finish'}); +} + +info("Creating XHR..."); +var xhr = new XMLHttpRequest(); +xhr.open("POST", "echo.sjs"); +xhr.responseType = 'arraybuffer'; + +info("Sending some data..."); +var data = new Array(256).join("1234567890ABCDEF"); +xhr.send({toString: function() { return data; }}); + +var aborted = false; + +xhr.onprogress = function() { + info("Onprogress, we abort!"); + aborted = true; + xhr.abort(); +} + +xhr.onloadend = function() { + ok(aborted, "We are still alive after an abort()!"); + finish(); +} diff --git a/dom/xhr/tests/worker_file_getcookie.sjs b/dom/xhr/tests/worker_file_getcookie.sjs new file mode 100644 index 000000000..b5204bdd7 --- /dev/null +++ b/dom/xhr/tests/worker_file_getcookie.sjs @@ -0,0 +1,15 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +function handleRequest(request, response) { + try { + var cookie = request.getHeader("Cookie"); + } catch (e) { + cookie = "EMPTY_COOKIE"; + } + + // avoid confusing cache behaviors. + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-type", "text/plain", false); + response.setStatusLine(request.httpVersion, "200", "OK"); + response.write(cookie); +} diff --git a/dom/xhr/tests/worker_temporaryFileBlob.js b/dom/xhr/tests/worker_temporaryFileBlob.js new file mode 100644 index 000000000..db40f72a8 --- /dev/null +++ b/dom/xhr/tests/worker_temporaryFileBlob.js @@ -0,0 +1,29 @@ +importScripts('common_temporaryFileBlob.js'); + +function info(msg) { + postMessage({type: 'info', msg: msg}); +} + +function ok(a, msg) { + postMessage({type: 'check', what: !!a, msg: msg}); +} + +function is(a, b, msg) { + ok(a === b, msg); +} + +function next() { + postMessage({type: 'finish'}); +} + +onmessage = function(e) { + if (e.data == 'simple') { + test_simple(); + } else if (e.data == 'abort') { + test_abort(); + } else if (e.data == 'reuse') { + test_reuse(); + } else { + ok(false, 'Something wrong happened'); + } +} diff --git a/dom/xhr/tests/worker_terminateSyncXHR_frame.html b/dom/xhr/tests/worker_terminateSyncXHR_frame.html new file mode 100644 index 000000000..04bd53ff1 --- /dev/null +++ b/dom/xhr/tests/worker_terminateSyncXHR_frame.html @@ -0,0 +1,25 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> + <head> + <title>Test for SharedWorker</title> + </head> + <body> + <script type="text/javascript"> + function doStuff() { + var worker = new Worker("terminateSyncXHR_worker.js"); + + worker.onmessage = function(event) { + parent.postMessage(event.data, "*"); + }; + + worker.onerror = function(event) { + parent.postMessage("ERROR!", "*"); + } + } + </script> + </body> +</html> diff --git a/dom/xhr/tests/worker_testXHR.txt b/dom/xhr/tests/worker_testXHR.txt new file mode 100644 index 000000000..2beab22c6 --- /dev/null +++ b/dom/xhr/tests/worker_testXHR.txt @@ -0,0 +1 @@ +A noisy noise annoys an oyster.
\ No newline at end of file diff --git a/dom/xhr/tests/worker_xhr_cors_redirect.js b/dom/xhr/tests/worker_xhr_cors_redirect.js new file mode 100644 index 000000000..c006b4a2e --- /dev/null +++ b/dom/xhr/tests/worker_xhr_cors_redirect.js @@ -0,0 +1,10 @@ +onmessage = function(e) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', e.data, true); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + postMessage(xhr.status); + } + }; + xhr.send(); +}; diff --git a/dom/xhr/tests/worker_xhr_cors_redirect.sjs b/dom/xhr/tests/worker_xhr_cors_redirect.sjs new file mode 100644 index 000000000..07e8ed5dc --- /dev/null +++ b/dom/xhr/tests/worker_xhr_cors_redirect.sjs @@ -0,0 +1,10 @@ +function handleRequest(request, response) { + response.setHeader("Access-Control-Allow-Origin", "*"); + + if (request.queryString == 'redirect') { + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", "worker_xhr_cors_redirect.sjs"); + } else { + response.write("'hello world'"); + } +} diff --git a/dom/xhr/tests/worker_xhr_headers_server.sjs b/dom/xhr/tests/worker_xhr_headers_server.sjs new file mode 100644 index 000000000..624abb9fc --- /dev/null +++ b/dom/xhr/tests/worker_xhr_headers_server.sjs @@ -0,0 +1,66 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +"use strict"; + +function handleRequest(request, response) { + switch (request.method) { + case "POST": + try { + var optionsHost = request.getHeader("options-host"); + } catch(e) { } + + var headerFound = false; + if (optionsHost) { + setState("postHost", request.host); + setState("optionsHost", optionsHost); + headerFound = true; + } + + try { + var emptyHeader = "nada" + request.getHeader("empty"); + } catch(e) { } + + if (emptyHeader && emptyHeader == "nada") { + setState("emptyHeader", "nada"); + headerFound = true; + } + if (headerFound) { + return; + } else { + break; + } + + case "OPTIONS": + if (getState("optionsHost") == request.host) { + try { + var optionsHeader = + request.getHeader("Access-Control-Request-Headers"); + } catch(e) { } + setState("optionsHeader", "'" + optionsHeader + "'"); + } + break; + + case "GET": + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/plain", false); + + if (getState("postHost") == request.host && + getState("emptyHeader") == "nada") { + var result = getState("optionsHeader"); + if (result) { + response.write("Success: expected OPTIONS request with " + result + + " header"); + } else if (getState("badGet") == 1) { + response.write("Error: unexpected GET request"); + } + } else { + setState("badGet", "1"); + response.write("Error: this response should never be seen"); + } + return; + } + + response.setStatusLine(request.httpVersion, 501, "Not Implemented"); +} diff --git a/dom/xhr/tests/worker_xhr_headers_worker.js b/dom/xhr/tests/worker_xhr_headers_worker.js new file mode 100644 index 000000000..af88b83ca --- /dev/null +++ b/dom/xhr/tests/worker_xhr_headers_worker.js @@ -0,0 +1,16 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +"use strict"; + +var customHeader = "custom-key"; +var customHeaderValue = "custom-key-value"; + +self.onmessage = function(event) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", event.data, false); + xhr.setRequestHeader(customHeader, customHeaderValue); + xhr.send(); + postMessage({ response: xhr.responseText, header: customHeader }); +} diff --git a/dom/xhr/tests/xhr2_worker.js b/dom/xhr/tests/xhr2_worker.js new file mode 100644 index 000000000..d355020c9 --- /dev/null +++ b/dom/xhr/tests/xhr2_worker.js @@ -0,0 +1,163 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +onmessage = function(event) { + const url = event.data; + + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, false); + xhr.send(); + + const refText = xhr.responseText; + + function getResponse(type) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, false); + if (type !== undefined) { + xhr.responseType = type; + } + xhr.send(); + return xhr.response; + } + + if (getResponse() != refText) { + throw new Error("unset responseType failed"); + } + + if (getResponse("") != refText) { + throw new Error("'' responseType failed"); + } + + if (getResponse("text") != refText) { + throw new Error("'text' responseType failed"); + } + + var array = new Uint8Array(getResponse("arraybuffer")); + if (String.fromCharCode.apply(String, array) != refText) { + throw new Error("'arraybuffer' responseType failed"); + } + + var blob = getResponse("blob"); + if (new FileReaderSync().readAsText(blob) != refText) { + throw new Error("'blob' responseType failed"); + } + + // Make sure that we get invalid state exceptions when getting the wrong + // property. + + function testResponseTextException(type) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, false); + xhr.responseType = type; + xhr.send(); + + var exception; + + try { + xhr.responseText; + } + catch(e) { + exception = e; + } + + if (!exception) { + throw new Error("Failed to throw when getting responseText on '" + type + + "' type"); + } + + if (exception.name != "InvalidStateError") { + throw new Error("Unexpected error when getting responseText on '" + type + + "' type"); + } + + if (exception.code != DOMException.INVALID_STATE_ERR) { + throw new Error("Unexpected error code when getting responseText on '" + type + + "' type"); + } + } + + testResponseTextException("arraybuffer"); + testResponseTextException("blob"); + + // Make sure "document" works, but returns text. + xhr = new XMLHttpRequest(); + + if (xhr.responseType != "text") { + throw new Error("Default value for responseType is wrong!"); + } + + xhr.open("GET", url, false); + xhr.responseType = "document"; + xhr.send(); + + if (xhr.responseText != refText) { + throw new Error("'document' type not working correctly"); + } + + // Make sure setting responseType before open or after send fails. + var exception; + + xhr = new XMLHttpRequest(); + xhr.open("GET", url); + xhr.responseType = "text"; + xhr.onload = function(event) { + if (event.target.response != refText) { + throw new Error("Bad response!"); + } + + xhr = new XMLHttpRequest(); + xhr.open("GET", url); + xhr.responseType = "moz-chunked-text"; + + var lastIndex = 0; + xhr.onprogress = function(event) { + if (refText.substr(lastIndex, xhr.response.length) != xhr.response) { + throw new Error("Bad chunk!"); + } + + lastIndex += xhr.response.length; + }; + + xhr.onload = function(event) { + if (lastIndex != refText.length) { + throw new Error("Didn't see all the data!"); + } + + setTimeout(function() { + if (xhr.response !== null) { + throw new Error("Should have gotten null response outside of event!"); + } + postMessage("done"); + }, 0); + } + + xhr.send(null); + }; + xhr.send(); + + exception = null; + + try { + xhr.responseType = "arraybuffer"; + } + catch(e) { + exception = e; + } + + if (!exception) { + throw new Error("Failed to throw when setting responseType after " + + "calling send()"); + } + + if (exception.name != "InvalidStateError") { + throw new Error("Unexpected error when setting responseType after " + + "calling send()"); + } + + if (exception.code != DOMException.INVALID_STATE_ERR) { + throw new Error("Unexpected error code when setting responseType after " + + "calling send()"); + } +} diff --git a/dom/xhr/tests/xhrAbort_worker.js b/dom/xhr/tests/xhrAbort_worker.js new file mode 100644 index 000000000..281781761 --- /dev/null +++ b/dom/xhr/tests/xhrAbort_worker.js @@ -0,0 +1,92 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +function runTest() { + var xhr = new XMLHttpRequest(); + + var events = []; + function pushEvent(event) { + var readyState, responseText, status, statusText; + + try { + readyState = xhr.readyState; + } + catch (e) { + readyState = "[exception]"; + } + + try { + responseText = xhr.responseText; + } + catch (e) { + responseText = "[exception]"; + } + + try { + status = xhr.status; + } + catch (e) { + status = "[exception]"; + } + + try { + statusText = xhr.statusText; + } + catch (e) { + statusText = "[exception]"; + } + + var str = event.type + "(" + readyState + ", '" + responseText + "', " + + status + ", '" + statusText + "'"; + if ((("ProgressEvent" in this) && event instanceof ProgressEvent) || + (("WorkerProgressEvent" in this) && event instanceof WorkerProgressEvent)) { + str += ", progressEvent"; + } + str += ")"; + + events.push(str); + } + + xhr.onerror = function(event) { + throw new Error("Error: " + xhr.statusText); + } + + xhr.onload = function(event) { + throw new Error("Shouldn't have gotten load event!"); + }; + + var seenAbort; + xhr.onabort = function(event) { + if (seenAbort) { + throw new Error("Already seen the abort event!"); + } + seenAbort = true; + + pushEvent(event); + postMessage(events); + }; + + xhr.onreadystatechange = function(event) { + pushEvent(event); + if (xhr.readyState == xhr.HEADERS_RECEIVED) { + xhr.abort(); + } + }; + + xhr.open("GET", "worker_testXHR.txt"); + xhr.overrideMimeType("text/plain"); + xhr.send(null); +} + +function messageListener(event) { + switch (event.data) { + case "start": + runTest(); + break; + default: + throw new Error("Bad message!"); + } +} + +addEventListener("message", messageListener, false); diff --git a/dom/xhr/tests/xhr_implicit_cancel_worker.js b/dom/xhr/tests/xhr_implicit_cancel_worker.js new file mode 100644 index 000000000..2045452ca --- /dev/null +++ b/dom/xhr/tests/xhr_implicit_cancel_worker.js @@ -0,0 +1,10 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +var xhr = new XMLHttpRequest(); +xhr.open("GET", "worker_testXHR.txt"); +xhr.send(null); +xhr.open("GET", "worker_testXHR.txt"); +xhr.send(null); +postMessage("done"); diff --git a/dom/xhr/tests/xhr_worker.js b/dom/xhr/tests/xhr_worker.js new file mode 100644 index 000000000..178c391b6 --- /dev/null +++ b/dom/xhr/tests/xhr_worker.js @@ -0,0 +1,84 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +var xhr = new XMLHttpRequest(); + +function onload(event) { + if (event.target != xhr) { + throw "onload event.target != xhr"; + } + + if (event.target.status != 200) { + var message = { type: "error", + error: event.target.status }; + postMessage(message); + } + + var message = { type: "load", + data: xhr.responseText }; + postMessage(message); +} + +xhr.onload = onload; +xhr.addEventListener("load", onload, false); +xhr.removeEventListener("load", onload, false); +if (!xhr.onload) { + var message = { type: "error", + error: "Lost message listener!" }; + postMessage(message); +} + +xhr.onerror = function(event) { + if (event.target != xhr) { + throw "onerror event.target != xhr"; + } + var message = { type: "error", + error: event.target.status }; + postMessage(message); +}; +xhr.onerror = xhr.onerror; +if (!xhr.onerror || xhr.onerror != xhr.onerror) { + throw "onerror wasn't set properly"; +} + +function onprogress(event) { + if (event.target != xhr) { + throw "onprogress event.target != xhr"; + } + var message = { type: "progress", + current: event.loaded, + total: event.total }; + postMessage(message); +} +xhr.addEventListener("progress", onprogress, false); + +xhr.addEventListener("foopety", function(event) {}, false); +xhr.removeEventListener("doopety", function(event) {}, false); + +xhr.onloadend = function(event) { + var message = { type: "loadend" }; + postMessage(message); +} + +var upload = xhr.upload; +upload.onprogress = function(event) { }; +upload.addEventListener("foo", function(event) { }, false); +upload.removeEventListener("foo", function(event) { }, false); +upload.addEventListener("load", function(event) { }, false); +upload.removeEventListener("foo", function(event) { }, false); +upload.onload = function(event) { + var message = { type: "upload.load" }; + postMessage(message); +} + +onmessage = function(event) { + if (xhr.DONE != 4 || XMLHttpRequest.DONE != 4) { + throw "xhr constants not correct!"; + } + if (xhr.readystate > xhr.UNSENT) { + throw "XHR already running!"; + } + xhr.open("POST", event.data); + xhr.send("Data to send"); +} |