summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/XMLHttpRequest/resources
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /testing/web-platform/tests/XMLHttpRequest/resources
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'testing/web-platform/tests/XMLHttpRequest/resources')
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/accept-language.py4
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/accept.py3
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth1/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth2/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth2/corsenabled.py20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth3/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth4/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth5/auth.py13
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth6/auth.py13
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth7/corsenabled.py20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth8/corsenabled-no-authorize.py20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth9/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/authentication.py32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/chunked.py18
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/conditional.py17
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/content.py18
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/corsenabled.py20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/delay.py6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/echo-method.py6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/empty-div-utf8-html.py5
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/folder.txt1
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/form.py2
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/gzip.py23
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/headers.py12
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/image.gifbin0 -> 167145 bytes
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/img-utf8-html.py5
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/img.jpgbin0 -> 108761 bytes
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/infinite-redirects.py24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/init.htm20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/inspect-headers.py22
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/invalid-utf8-html.py5
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/last-modified.py7
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/nocors/folder.txt1
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/parse-headers.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/redirect.py8
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/requri.py6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-1.htm23
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-2.htm20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-helper.js29
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/shift-jis-html.py6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/status.py9
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/trickle.py15
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/upload.py15
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/utf16.txtbin0 -> 18 bytes
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/well-formed.xml4
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/win-1252-xml.py5
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-origin-referrer.js34
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-simple.js10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js83
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-aborted.js15
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-abortedonmain.js8
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overrides.js11
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overridesexpires.js12
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-runner.js21
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-simple.js6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconmain.js2
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconworker.js11
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-twice.js6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout.js325
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/zlib.py19
60 files changed, 1100 insertions, 0 deletions
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/accept-language.py b/testing/web-platform/tests/XMLHttpRequest/resources/accept-language.py
new file mode 100644
index 000000000..e0fd30c11
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/accept-language.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ return [("Content-Type", "text/plain"),
+ request.headers.get("Accept-Language", "NO")]
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/accept.py b/testing/web-platform/tests/XMLHttpRequest/resources/accept.py
new file mode 100644
index 000000000..2fdf210b6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/accept.py
@@ -0,0 +1,3 @@
+def main(request, response):
+ return [("Content-Type", "text/plain")], request.headers.get("accept", "NO")
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth1/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth1/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth1/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth2/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth2/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth2/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth2/corsenabled.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth2/corsenabled.py
new file mode 100644
index 000000000..ce2269739
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth2/corsenabled.py
@@ -0,0 +1,20 @@
+import imp
+import os
+
+def main(request, response):
+ response.headers.set('Access-Control-Allow-Origin', request.headers.get("origin"));
+ response.headers.set('Access-Control-Allow-Credentials', 'true');
+ response.headers.set('Access-Control-Allow-Methods', 'GET');
+ response.headers.set('Access-Control-Allow-Headers', 'authorization, x-user, x-pass');
+ response.headers.set('Access-Control-Expose-Headers', 'x-challenge, xhr-user, ses-user');
+ auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
+ "XMLHttpRequest",
+ "resources",
+ "authentication.py"))
+ if request.method == "OPTIONS":
+ return ""
+ else:
+ return auth.main(request, response)
+
+
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth3/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth3/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth3/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth4/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth4/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth4/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth5/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth5/auth.py
new file mode 100644
index 000000000..bc739f5eb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth5/auth.py
@@ -0,0 +1,13 @@
+def main(request, response):
+ if request.auth.username == 'usr' and request.auth.password == 'secret':
+ response.headers.set('Content-type', 'text/plain')
+ content = ""
+ else:
+ response.status = 401
+ response.headers.set('Status', '401 Authorization required')
+ response.headers.set('WWW-Authenticate', 'Basic realm="test"')
+ content = 'User name/password wrong or not given: '
+
+ content += "%s\n%s" % (request.auth.username,
+ request.auth.password)
+ return content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth6/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth6/auth.py
new file mode 100644
index 000000000..bc739f5eb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth6/auth.py
@@ -0,0 +1,13 @@
+def main(request, response):
+ if request.auth.username == 'usr' and request.auth.password == 'secret':
+ response.headers.set('Content-type', 'text/plain')
+ content = ""
+ else:
+ response.status = 401
+ response.headers.set('Status', '401 Authorization required')
+ response.headers.set('WWW-Authenticate', 'Basic realm="test"')
+ content = 'User name/password wrong or not given: '
+
+ content += "%s\n%s" % (request.auth.username,
+ request.auth.password)
+ return content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth7/corsenabled.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth7/corsenabled.py
new file mode 100644
index 000000000..ce2269739
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth7/corsenabled.py
@@ -0,0 +1,20 @@
+import imp
+import os
+
+def main(request, response):
+ response.headers.set('Access-Control-Allow-Origin', request.headers.get("origin"));
+ response.headers.set('Access-Control-Allow-Credentials', 'true');
+ response.headers.set('Access-Control-Allow-Methods', 'GET');
+ response.headers.set('Access-Control-Allow-Headers', 'authorization, x-user, x-pass');
+ response.headers.set('Access-Control-Expose-Headers', 'x-challenge, xhr-user, ses-user');
+ auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
+ "XMLHttpRequest",
+ "resources",
+ "authentication.py"))
+ if request.method == "OPTIONS":
+ return ""
+ else:
+ return auth.main(request, response)
+
+
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth8/corsenabled-no-authorize.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth8/corsenabled-no-authorize.py
new file mode 100644
index 000000000..cb40efb08
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth8/corsenabled-no-authorize.py
@@ -0,0 +1,20 @@
+import imp
+import os
+
+def main(request, response):
+ response.headers.set('Access-Control-Allow-Origin', request.headers.get("origin"));
+ response.headers.set('Access-Control-Allow-Credentials', 'true');
+ response.headers.set('Access-Control-Allow-Methods', 'GET');
+ response.headers.set('Access-Control-Allow-Headers', 'x-user, x-pass');
+ response.headers.set('Access-Control-Expose-Headers', 'x-challenge, xhr-user, ses-user');
+ auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
+ "XMLHttpRequest",
+ "resources",
+ "authentication.py"))
+ if request.method == "OPTIONS":
+ return ""
+ else:
+ return auth.main(request, response)
+
+
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth9/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth9/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth9/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/authentication.py b/testing/web-platform/tests/XMLHttpRequest/resources/authentication.py
new file mode 100644
index 000000000..4f65fa23d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/authentication.py
@@ -0,0 +1,32 @@
+def main(request, response):
+ if "logout" in request.GET:
+ return ((401, "Unauthorized"),
+ [("WWW-Authenticate", 'Basic realm="test"')],
+ "Logged out, hopefully")
+
+ session_user = request.auth.username
+ session_pass = request.auth.password
+ expected_user_name = request.headers.get("X-User", None)
+
+ token = expected_user_name
+ if session_user is None and session_pass is None:
+ if token is not None and request.server.stash.take(token) is not None:
+ return 'FAIL (did not authorize)'
+ else:
+ if token is not None:
+ request.server.stash.put(token, "1")
+ status = (401, 'Unauthorized')
+ headers = [('WWW-Authenticate', 'Basic realm="test"'),
+ ('XHR-USER', expected_user_name),
+ ('SES-USER', session_user)]
+ return status, headers, 'FAIL (should be transparent)'
+ else:
+ if request.server.stash.take(token) == "1":
+ challenge = "DID"
+ else:
+ challenge = "DID-NOT"
+ headers = [('XHR-USER', expected_user_name),
+ ('SES-USER', session_user),
+ ("X-challenge", challenge)]
+ return headers, session_user + "\n" + session_pass;
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/chunked.py b/testing/web-platform/tests/XMLHttpRequest/resources/chunked.py
new file mode 100644
index 000000000..7e8433bd8
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/chunked.py
@@ -0,0 +1,18 @@
+def main(request, response):
+ chunks = ["First chunk\r\n",
+ "Second chunk\r\n",
+ "Yet another (third) chunk\r\n",
+ "Yet another (fourth) chunk\r\n",
+ ]
+ response.headers.set("Transfer-Encoding", "chunked");
+ response.headers.set("Trailer", "X-Test-Me");
+ response.headers.set("Content-Type", "text/plain");
+ response.write_status_headers()
+
+ for value in chunks:
+ response.writer.write("%x\r\n" % len(value))
+ response.writer.write(value)
+ response.writer.write("\r\n")
+ response.writer.write("0\r\n")
+ response.writer.write("X-Test-Me: Trailer header value\r\n\r\n")
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/conditional.py b/testing/web-platform/tests/XMLHttpRequest/resources/conditional.py
new file mode 100644
index 000000000..42dfecdfb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/conditional.py
@@ -0,0 +1,17 @@
+def main(request, response):
+ tag = request.GET.first("tag", None)
+ match = request.headers.get("If-None-Match", None)
+ date = request.GET.first("date", "")
+ modified = request.headers.get("If-Modified-Since", None)
+ if tag:
+ response.headers.set("ETag", '"%s"' % tag)
+ elif date:
+ response.headers.set("Last-Modified", date)
+
+ if ((match is not None and match == tag) or
+ (modified is not None and modified == date)):
+ response.status = (304, "SUPERCOOL")
+ return ""
+ else:
+ response.headers.set("Content-Type", "text/plain")
+ return "MAYBE NOT"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/content.py b/testing/web-platform/tests/XMLHttpRequest/resources/content.py
new file mode 100644
index 000000000..d7c62ab6d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/content.py
@@ -0,0 +1,18 @@
+def main(request, response):
+ response_ctype = ''
+
+ if "response_charset_label" in request.GET:
+ response_ctype = ";charset=" + request.GET.first("response_charset_label")
+
+ headers = [("Content-type", "text/plain" + response_ctype),
+ ("X-Request-Method", request.method),
+ ("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"),
+ ("X-Request-Content-Length", request.headers.get("Content-Length", "NO")),
+ ("X-Request-Content-Type", request.headers.get("Content-Type", "NO"))]
+
+ if "content" in request.GET:
+ content = request.GET.first("content")
+ else:
+ content = request.body
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/corsenabled.py b/testing/web-platform/tests/XMLHttpRequest/resources/corsenabled.py
new file mode 100644
index 000000000..1f0f878f4
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/corsenabled.py
@@ -0,0 +1,20 @@
+import time
+
+def main(request, response):
+ headers = [("Access-Control-Allow-Origin", "*"),
+ ("Access-Control-Allow-Credentials", "true"),
+ ("Access-Control-Allow-Methods", "GET, POST, PUT, FOO"),
+ ("Access-Control-Allow-Headers", "x-test, x-foo"),
+ ("Access-Control-Expose-Headers", "x-request-method, x-request-content-type, x-request-query, x-request-content-length, x-request-data")]
+
+ if "delay" in request.GET:
+ delay = int(request.GET.first("delay"))
+ time.sleep(delay)
+
+ headers.append(("X-Request-Method", request.method))
+ headers.append(("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"))
+ headers.append(("X-Request-Content-Length", request.headers.get("Content-Length", "NO")))
+ headers.append(("X-Request-Content-Type", request.headers.get("Content-Type", "NO")))
+ headers.append(("X-Request-Data", request.body))
+
+ return headers, "Test"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/delay.py b/testing/web-platform/tests/XMLHttpRequest/resources/delay.py
new file mode 100644
index 000000000..bdfef9b34
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/delay.py
@@ -0,0 +1,6 @@
+import time
+
+def main(request, response):
+ delay = float(request.GET.first("ms", 500))
+ time.sleep(delay / 1E3);
+ return [("Content-type", "text/plain")], "TEST_DELAY"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/echo-method.py b/testing/web-platform/tests/XMLHttpRequest/resources/echo-method.py
new file mode 100644
index 000000000..5351d1961
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/echo-method.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ response.send_body_for_head_request = True
+ headers = [("Content-type", "text/plain")]
+ content = request.method
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/empty-div-utf8-html.py b/testing/web-platform/tests/XMLHttpRequest/resources/empty-div-utf8-html.py
new file mode 100644
index 000000000..26d54b9d1
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/empty-div-utf8-html.py
@@ -0,0 +1,5 @@
+def main(request, response):
+ headers = [("Content-type", "text/html;charset=utf-8")]
+ content = "<!DOCTYPE html><div></div>"
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/folder.txt b/testing/web-platform/tests/XMLHttpRequest/resources/folder.txt
new file mode 100644
index 000000000..fef12e219
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/folder.txt
@@ -0,0 +1 @@
+bottom
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/form.py b/testing/web-platform/tests/XMLHttpRequest/resources/form.py
new file mode 100644
index 000000000..6b1c49a99
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/form.py
@@ -0,0 +1,2 @@
+def main(request, response):
+ return "id:%s;value:%s;" % (request.POST.first("id"), request.POST.first("value"))
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/gzip.py b/testing/web-platform/tests/XMLHttpRequest/resources/gzip.py
new file mode 100644
index 000000000..87dd5bec0
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/gzip.py
@@ -0,0 +1,23 @@
+import gzip as gzip_module
+from cStringIO import StringIO
+
+def main(request, response):
+ if "content" in request.GET:
+ output = request.GET["content"]
+ else:
+ output = request.body
+
+ out = StringIO()
+ with gzip_module.GzipFile(fileobj=out, mode="w") as f:
+ f.write(output)
+ output = out.getvalue()
+
+ headers = [("Content-type", "text/plain"),
+ ("Content-Encoding", "gzip"),
+ ("X-Request-Method", request.method),
+ ("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"),
+ ("X-Request-Content-Length", request.headers.get("Content-Length", "NO")),
+ ("X-Request-Content-Type", request.headers.get("Content-Type", "NO")),
+ ("Content-Length", len(output))]
+
+ return headers, output
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/headers.py b/testing/web-platform/tests/XMLHttpRequest/resources/headers.py
new file mode 100644
index 000000000..cefa8ee65
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/headers.py
@@ -0,0 +1,12 @@
+ # -*- coding: utf-8 -*-
+
+def main(request, response):
+ response.headers.set("Content-Type", "text/plain")
+ response.headers.set("X-Custom-Header", "test")
+ response.headers.set("Set-Cookie", "test")
+ response.headers.set("Set-Cookie2", "test")
+ response.headers.set("X-Custom-Header-Empty", "")
+ response.headers.set("X-Custom-Header-Comma", "1")
+ response.headers.append("X-Custom-Header-Comma", "2")
+ response.headers.set("X-Custom-Header-Bytes", "…")
+ return "TEST"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/image.gif b/testing/web-platform/tests/XMLHttpRequest/resources/image.gif
new file mode 100644
index 000000000..6d1174af1
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/image.gif
Binary files differ
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/img-utf8-html.py b/testing/web-platform/tests/XMLHttpRequest/resources/img-utf8-html.py
new file mode 100644
index 000000000..085867f95
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/img-utf8-html.py
@@ -0,0 +1,5 @@
+def main(request, response):
+ headers = [("Content-type", "text/html;charset=utf-8")]
+ content = "<img>foo"
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/img.jpg b/testing/web-platform/tests/XMLHttpRequest/resources/img.jpg
new file mode 100644
index 000000000..7aa936252
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/img.jpg
Binary files differ
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/infinite-redirects.py b/testing/web-platform/tests/XMLHttpRequest/resources/infinite-redirects.py
new file mode 100644
index 000000000..b508c5b3c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/infinite-redirects.py
@@ -0,0 +1,24 @@
+def main(request, response):
+ location = "%s://%s:%s/%s" % (request.url_parts.scheme,
+ request.url_parts.netloc,
+ request.url_parts.port,
+ request.url_parts.path)
+ page = "alternate";
+ type = 302;
+ mix = 0;
+ if request.GET.first("page", None) == "alternate":
+ page = "default"
+
+ if request.GET.first("type", None) == "301":
+ type = 301
+
+ if request.GET.first("mix", None) == "1":
+ mix = 1
+ type = 302 if type == 301 else 301
+
+ new_location = "%s?page=%s&type=%s&mix=%s" % (location, page, type, mix)
+ headers = [("Cache-Control", "no-cache"),
+ ("Pragma", "no-cache"),
+ ("Location", new_location)]
+ return 301, headers, "Hello guest. You have been redirected to " + new_location
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/init.htm b/testing/web-platform/tests/XMLHttpRequest/resources/init.htm
new file mode 100644
index 000000000..6f936c4fb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/init.htm
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <title>support init file</title>
+ </head>
+ <body>
+ <script>
+ onload = function() {
+ // Run async, because navigations from inside onload can be a bit weird.
+ setTimeout(function() {
+ if (parent != window) {
+ parent.init()
+ } else {
+ opener.init();
+ }
+ }, 0);
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/inspect-headers.py b/testing/web-platform/tests/XMLHttpRequest/resources/inspect-headers.py
new file mode 100644
index 000000000..ca5960557
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/inspect-headers.py
@@ -0,0 +1,22 @@
+def main(request, response):
+ headers = []
+ if "cors" in request.GET:
+ headers.append(("Access-Control-Allow-Origin", "*"))
+ headers.append(("Access-Control-Allow-Credentials", "true"))
+ headers.append(("Access-Control-Allow-Methods", "GET, POST, PUT, FOO"))
+ headers.append(("Access-Control-Allow-Headers", "x-test, x-foo"))
+ headers.append(("Access-Control-Expose-Headers", "x-request-method, x-request-content-type, x-request-query, x-request-content-length"))
+
+ filter_value = request.GET.first("filter_value", "")
+ filter_name = request.GET.first("filter_name", "").lower()
+
+ result = ""
+ for name, value in request.headers.iteritems():
+ if filter_value:
+ if value == filter_value:
+ result += name.lower() + ","
+ elif name.lower() == filter_name:
+ result += name.lower() + ": " + value + "\n";
+
+ headers.append(("content-type", "text/plain"))
+ return headers, result
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/invalid-utf8-html.py b/testing/web-platform/tests/XMLHttpRequest/resources/invalid-utf8-html.py
new file mode 100644
index 000000000..72be41a45
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/invalid-utf8-html.py
@@ -0,0 +1,5 @@
+def main(request, response):
+ headers = [("Content-type", "text/html;charset=utf-8")]
+ content = chr(0xff)
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/last-modified.py b/testing/web-platform/tests/XMLHttpRequest/resources/last-modified.py
new file mode 100644
index 000000000..ef05a6343
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/last-modified.py
@@ -0,0 +1,7 @@
+def main(request, response):
+ import datetime, os
+ srcpath = os.path.join(os.path.dirname(__file__), "well-formed.xml")
+ srcmoddt = datetime.datetime.fromtimestamp(os.path.getmtime(srcpath))
+ response.headers.set("Last-Modified", srcmoddt.strftime("%a, %d %b %Y %H:%M:%S GMT"))
+ response.headers.set("Content-Type", "application/xml")
+ return open(srcpath, "r").read()
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/nocors/folder.txt b/testing/web-platform/tests/XMLHttpRequest/resources/nocors/folder.txt
new file mode 100644
index 000000000..5257b481d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/nocors/folder.txt
@@ -0,0 +1 @@
+not CORS-enabled \ No newline at end of file
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/parse-headers.py b/testing/web-platform/tests/XMLHttpRequest/resources/parse-headers.py
new file mode 100644
index 000000000..fdc626539
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/parse-headers.py
@@ -0,0 +1,10 @@
+import json
+
+def main(request, response):
+
+ content = ""
+ if "my-custom-header" in request.GET:
+ val = request.GET.first("my-custom-header")
+ response.headers.set("My-Custom-Header", val)
+
+ return content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/redirect.py b/testing/web-platform/tests/XMLHttpRequest/resources/redirect.py
new file mode 100644
index 000000000..6ec934956
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/redirect.py
@@ -0,0 +1,8 @@
+def main(request, response):
+ code = int(request.GET.first("code", 302))
+ location = request.GET.first("location", request.url_parts.path +"?followed")
+
+ if request.url.endswith("?followed"):
+ return [("Content:Type", "text/plain")], "MAGIC HAPPENED"
+ else:
+ return (code, "WEBSRT MARKETING"), [("Location", location)], "TEST"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/requri.py b/testing/web-platform/tests/XMLHttpRequest/resources/requri.py
new file mode 100644
index 000000000..eaa562dff
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/requri.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ if "full" in request.GET:
+ return request.url
+ else:
+ return request.request_path
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-1.htm b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-1.htm
new file mode 100644
index 000000000..4e4c3faff
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-1.htm
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() with document.domain set: loading documents from original origin after setting document.domain</title>
+ <script src="send-after-setting-document-domain-window-helper.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[3]" />
+ </head>
+ <body>
+ <script>
+ run_test(function() {
+ document.domain = document.domain; // this is not a noop, it does actually change the security context
+ var client = new XMLHttpRequest();
+ client.open("GET", "status.py?content=hello", false);
+ client.send(null);
+ assert_equals(client.responseText, "hello");
+ document.domain = document.domain.replace(/^\w+\./, "");
+ client.open("GET", "status.py?content=hello2", false);
+ client.send(null);
+ assert_equals(client.responseText, "hello2");
+ }, "loading documents from original origin after setting document.domain");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-2.htm b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-2.htm
new file mode 100644
index 000000000..073268c21
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-2.htm
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() with document.domain set: loading documents from the origin document.domain was set to should throw</title>
+ <script src="send-after-setting-document-domain-window-helper.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[3]" />
+ </head>
+ <body>
+ <script>
+ run_test(function() {
+ document.domain = document.domain.replace(/^\w+\./, "");
+ var client = new XMLHttpRequest();
+ client.open("GET", location.protocol + "//" + document.domain + location.pathname.replace(/[^\/]*$/, "") + "status.py?content=hello3", false);
+ assert_throws("NetworkError", function() {
+ client.send(null);
+ });
+ }, "loading documents from the origin document.domain was set to should throw");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-helper.js b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-helper.js
new file mode 100644
index 000000000..f5c762b04
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-helper.js
@@ -0,0 +1,29 @@
+function assert_equals(value, expected) {
+ if (value != expected) {
+ throw "Got wrong value.\nExpected '" + expected + "',\ngot '" + value + "'";
+ }
+}
+
+function assert_throws(expected_exc, func) {
+ try {
+ func.call(this);
+ } catch(e) {
+ var actual = e.name || e.type;
+ if (actual != expected_exc) {
+ throw "Got wrong exception.\nExpected '" + expected_exc + "',\ngot '" + actual + "'.";
+ }
+ return;
+ }
+ throw "Expected exception, but none was thrown";
+}
+
+function run_test(test, name) {
+ var result = {passed: true, message: null, name: name};
+ try {
+ test();
+ } catch(e) {
+ result.passed = false;
+ result.message = e + "";
+ }
+ opener.postMessage(result, "*");
+}
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/shift-jis-html.py b/testing/web-platform/tests/XMLHttpRequest/resources/shift-jis-html.py
new file mode 100644
index 000000000..92d06ca78
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/shift-jis-html.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ headers = [("Content-type", "text/html;charset=shift-jis")]
+ # Shift-JIS bytes for katakana TE SU TO ('test')
+ content = chr(0x83) + chr(0x65) + chr(0x83) + chr(0x58) + chr(0x83) + chr(0x67);
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/status.py b/testing/web-platform/tests/XMLHttpRequest/resources/status.py
new file mode 100644
index 000000000..5d72e10b2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/status.py
@@ -0,0 +1,9 @@
+def main(request, response):
+ code = int(request.GET.first("code", 200))
+ text = request.GET.first("text", "OMG")
+ content = request.GET.first("content", "")
+ type = request.GET.first("type", "")
+ status = (code, text)
+ headers = [("Content-Type", type),
+ ("X-Request-Method", request.method)]
+ return status, headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/trickle.py b/testing/web-platform/tests/XMLHttpRequest/resources/trickle.py
new file mode 100644
index 000000000..5a46c5e82
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/trickle.py
@@ -0,0 +1,15 @@
+import time
+
+def main(request, response):
+ chunk = "TEST_TRICKLE\n"
+ delay = float(request.GET.first("ms", 500)) / 1E3
+ count = int(request.GET.first("count", 50))
+ if "specifylength" in request.GET:
+ response.headers.set("Content-Length", count * len(chunk))
+ time.sleep(delay)
+ response.headers.set("Content-type", "text/plain")
+ response.write_status_headers()
+ time.sleep(delay);
+ for i in xrange(count):
+ response.writer.write_content(chunk)
+ time.sleep(delay)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/upload.py b/testing/web-platform/tests/XMLHttpRequest/resources/upload.py
new file mode 100644
index 000000000..27cee598b
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/upload.py
@@ -0,0 +1,15 @@
+def main(request, response):
+ content = []
+
+ for key, values in sorted(item for item in request.POST.items() if not hasattr(item[1][0], "filename")):
+ content.append("%s=%s," % (key, values[0]))
+ content.append("\n")
+
+ for key, values in sorted(item for item in request.POST.items() if hasattr(item[1][0], "filename")):
+ value = values[0]
+ content.append("%s=%s:%s:%s," % (key,
+ value.filename,
+ value.headers["Content-Type"],
+ len(value.file.read())))
+
+ return "".join(content)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/utf16.txt b/testing/web-platform/tests/XMLHttpRequest/resources/utf16.txt
new file mode 100644
index 000000000..0085dfaee
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/utf16.txt
Binary files differ
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/well-formed.xml b/testing/web-platform/tests/XMLHttpRequest/resources/well-formed.xml
new file mode 100644
index 000000000..2f4f12698
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/well-formed.xml
@@ -0,0 +1,4 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <p id="n&#49;">1</p>
+ <p xmlns="namespacesarejuststrings" id="n2">2</p>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/win-1252-xml.py b/testing/web-platform/tests/XMLHttpRequest/resources/win-1252-xml.py
new file mode 100644
index 000000000..09c32e457
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/win-1252-xml.py
@@ -0,0 +1,5 @@
+def main(request, response):
+ headers = [("Content-type", "application/xml;charset=windows-1252")]
+ content = '<' + chr(0xff) + '/>'
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-origin-referrer.js b/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-origin-referrer.js
new file mode 100644
index 000000000..5e2ef2a8c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-origin-referrer.js
@@ -0,0 +1,34 @@
+// This simply posts a message to the owner page with the contents of the Referer header
+var xhr=new XMLHttpRequest()
+xhr.onreadystatechange = function(){
+ if(xhr.readyState == 4){
+ var obj = {test:'Referer header', result:xhr.responseText}
+ self.postMessage(obj)
+ }
+}
+xhr.open('GET', 'inspect-headers.py?filter_name=referer', true)
+xhr.send()
+
+// This simply posts a message to the owner page with the contents of the Origin header
+var xhr2=new XMLHttpRequest()
+xhr2.onreadystatechange = function(){
+ if(xhr2.readyState == 4){
+ var obj = {test:'Origin header', result:xhr2.responseText}
+ self.postMessage(obj)
+ }
+}
+xhr2.open('GET', location.protocol + '//www2.'+location.hostname+((location.port === "")?"":":"+location.port)+(location.pathname.replace(/[^/]*$/, ''))+'inspect-headers.py?filter_name=origin&cors', true)
+xhr2.send()
+
+// If "origin" / base URL is the origin of this JS file, we can load files
+// from the server it originates from.. and requri.py will be able to tell us
+// what the requested URL was
+var xhr3=new XMLHttpRequest()
+xhr3.onreadystatechange = function(){
+ if(xhr3.readyState == 4){
+ var obj = {test:'Request URL test', result:xhr3.responseText}
+ self.postMessage(obj)
+ }
+}
+xhr3.open('GET', 'requri.py?full', true)
+xhr3.send()
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-simple.js b/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-simple.js
new file mode 100644
index 000000000..f6bcec0be
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-simple.js
@@ -0,0 +1,10 @@
+
+var xhr=new XMLHttpRequest()
+xhr.onreadystatechange = function(){
+ if(xhr.readyState == 4){
+ var status = xhr.responseText === 'bottom\n' ? 'PASSED' : 'FAILED'
+ self.postMessage(status)
+ }
+}
+xhr.open('GET', 'folder.txt', true)
+xhr.send()
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js
new file mode 100644
index 000000000..b6bb6cdf3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js
@@ -0,0 +1,83 @@
+(function(global) {
+ var recorded_xhr_events = [];
+
+ function record_xhr_event(e) {
+ var prefix = e.target instanceof XMLHttpRequestUpload ? "upload." : "";
+ recorded_xhr_events.push((prefix || "") + e.type + "(" + e.loaded + "," + e.total + "," + e.lengthComputable + ")");
+ }
+
+ global.prepare_xhr_for_event_order_test = function(xhr) {
+ xhr.addEventListener("readystatechange", function(e) {
+ recorded_xhr_events.push(xhr.readyState);
+ });
+ var events = ["loadstart", "progress", "abort", "timeout", "error", "load", "loadend"];
+ for(var i=0; i<events.length; ++i) {
+ xhr.addEventListener(events[i], record_xhr_event);
+ }
+ if ("upload" in xhr) {
+ for(var i=0; i<events.length; ++i) {
+ xhr.upload.addEventListener(events[i], record_xhr_event);
+ }
+ }
+ }
+
+ function getNextEvent(arr) {
+ var event = { str: arr.shift() };
+
+ // we can only handle strings, numbers (readystates) and undefined
+ if (event.str === undefined) {
+ return event;
+ }
+
+ if (typeof event.str !== "string") {
+ if (Number.isInteger(event.str)) {
+ event.state = event.str;
+ event.str = "readystatechange(" + event.str + ")";
+ } else {
+ throw "Test error: unexpected event type " + event.str;
+ }
+ }
+
+ // parse out the general type, loaded and total values
+ var type = event.type = event.str.split("(")[0].split(".").pop();
+ var loadedAndTotal = event.str.match(/.*\((\d+),(\d+),(true|false)\)/);
+ if (loadedAndTotal) {
+ event.loaded = parseInt(loadedAndTotal[1]);
+ event.total = parseInt(loadedAndTotal[2]);
+ event.lengthComputable = loadedAndTotal[3] == "true";
+ }
+
+ return event;
+ }
+
+ global.assert_xhr_event_order_matches = function(expected) {
+ var recorded = recorded_xhr_events;
+ var lastRecordedLoaded = -1;
+ while(expected.length && recorded.length) {
+ var currentExpected = getNextEvent(expected),
+ currentRecorded = getNextEvent(recorded);
+
+ // skip to the last progress event if we've hit one (note the next
+ // event after a progress event should be a LOADING readystatechange,
+ // if there are multiple progress events in a row).
+ while (recorded.length && currentRecorded.type == "progress" &&
+ parseInt(recorded) === 3) {
+ assert_greater_than(currentRecorded.loaded, lastRecordedLoaded,
+ "progress event 'loaded' values must only increase");
+ lastRecordedLoaded = currentRecorded.loaded;
+ }
+ if (currentRecorded.type == "loadend") {
+ recordedProgressCount = 0;
+ lastRecordedLoaded = -1;
+ }
+
+ assert_equals(currentRecorded.str, currentExpected.str);
+ }
+ if (recorded.length) {
+ throw "\nUnexpected extra events: " + recorded.join(", ");
+ }
+ if (expected.length) {
+ throw "\nExpected more events: " + expected.join(", ");
+ }
+ }
+}(this));
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-aborted.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-aborted.js
new file mode 100644
index 000000000..056d77c01
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-aborted.js
@@ -0,0 +1,15 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+/*
+This sets up three requests:
+The first request will only be open()ed, not aborted, timeout will be TIME_REGULAR_TIMEOUT but will never triggered because send() isn't called.
+After TIME_NORMAL_LOAD, the test asserts that no load/error/timeout/abort events fired
+
+Second request will be aborted immediately after send(), test asserts that abort fired
+
+Third request is set up to call abort() after TIME_NORMAL_LOAD, but it also has a TIME_REGULAR_TIMEOUT timeout. Asserts that timeout fired.
+(abort() is called later and should not fire an abort event per spec. This is untested!)
+*/
+runTestRequests([ new AbortedRequest(false),
+ new AbortedRequest(true, -1),
+ new AbortedRequest(true, TIME_NORMAL_LOAD) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-abortedonmain.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-abortedonmain.js
new file mode 100644
index 000000000..8dde8ef57
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-abortedonmain.js
@@ -0,0 +1,8 @@
+/*
+This test sets up two requests:
+one that gets abort()ed from a 0ms timeout (0ms will obviously be clamped to whatever the implementation's minimal value is), asserts abort event fires
+one that will be aborted after TIME_DELAY, (with a timeout at TIME_REGULAR_TIMEOUT) asserts abort event fires. Does not assert that the timeout event does *not* fire.
+*/
+
+runTestRequests([ new AbortedRequest(true, 0),
+ new AbortedRequest(true, TIME_DELAY) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overrides.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overrides.js
new file mode 100644
index 000000000..6dc2173b2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overrides.js
@@ -0,0 +1,11 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+/*
+Sets up three requests to a resource that will take 0.6 seconds to load:
+1) timeout first set to TIME_NORMAL_LOAD, after TIME_REGULAR_TIMEOUT timeout is set to 0, asserts load fires
+2) timeout first set to TIME_NORMAL_LOAD, after TIME_DELAY timeout is set to TIME_REGULAR_TIMEOUT, asserts load fires (race condition..?!?)
+3) timeout first set to 0, after TIME_REGULAR_TIMEOUT it is set to TIME_REGULAR_TIMEOUT * 10, asserts load fires
+*/
+runTestRequests([ new RequestTracker(true, "timeout disabled after initially set", TIME_NORMAL_LOAD, TIME_REGULAR_TIMEOUT, 0),
+ new RequestTracker(true, "timeout overrides load after a delay", TIME_NORMAL_LOAD, TIME_DELAY, TIME_REGULAR_TIMEOUT),
+ new RequestTracker(true, "timeout enabled after initially disabled", 0, TIME_REGULAR_TIMEOUT, TIME_NORMAL_LOAD * 10) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overridesexpires.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overridesexpires.js
new file mode 100644
index 000000000..bf251fa80
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overridesexpires.js
@@ -0,0 +1,12 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+/*
+ Starts three requests:
+ 1) XHR to resource which will take a least TIME_XHR_LOAD ms with timeout initially set to TIME_NORMAL_LOAD ms. After TIME_LATE_TIMEOUT ms timeout is supposedly reset to TIME_DELAY ms,
+ but the resource should have finished loading already. Asserts "load" fires.
+ 2) XHR with initial timeout set to TIME_NORMAL_LOAD, after TIME_REGULAR_TIMEOUT sets timeout to TIME_DELAY+100. Asserts "timeout" fires.
+ 3) XHR with initial timeout set to TIME_DELAY, after TIME_REGULAR_TIMEOUT sets timeout to 500ms. Asserts "timeout" fires (the change happens when timeout already fired and the request is done).
+*/
+runTestRequests([ new RequestTracker(true, "timeout set to expiring value after load fires", TIME_NORMAL_LOAD, TIME_LATE_TIMEOUT, TIME_DELAY),
+ new RequestTracker(true, "timeout set to expired value before load fires", TIME_NORMAL_LOAD, TIME_REGULAR_TIMEOUT, TIME_DELAY+100),
+ new RequestTracker(true, "timeout set to non-expiring value after timeout fires", TIME_DELAY, TIME_REGULAR_TIMEOUT, 500) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-runner.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-runner.js
new file mode 100644
index 000000000..151226a94
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-runner.js
@@ -0,0 +1,21 @@
+
+function testResultCallbackHandler(event) {
+ if (event.data == "done") {
+ done();
+ return;
+ }
+ if (event.data.type == "is") {
+ test(function() { assert_equals(event.data.got, event.data.expected); }, "Timeout test: " + event.data.msg);
+ return;
+ }
+ if (event.data.type == "ok") {
+ test(function() { assert_true(event.data.bool); }, "Timeout test: " + event.data.msg);
+ return;
+ }
+}
+
+window.addEventListener("message", testResultCallbackHandler);
+
+// Setting up testharness.js
+setup({ explicit_done: true });
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-simple.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-simple.js
new file mode 100644
index 000000000..0207cf107
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-simple.js
@@ -0,0 +1,6 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+
+runTestRequests([ new RequestTracker(true, "no time out scheduled, load fires normally", 0),
+ new RequestTracker(true, "load fires normally", TIME_NORMAL_LOAD),
+ new RequestTracker(true, "timeout hit before load", TIME_REGULAR_TIMEOUT) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconmain.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconmain.js
new file mode 100644
index 000000000..c6c5e985d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconmain.js
@@ -0,0 +1,2 @@
+runTestRequests([ SyncRequestSettingTimeoutAfterOpen,
+ SyncRequestSettingTimeoutBeforeOpen ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconworker.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconworker.js
new file mode 100644
index 000000000..5a6c3fc55
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconworker.js
@@ -0,0 +1,11 @@
+if (this.document === undefined){
+ importScripts("xmlhttprequest-timeout.js");
+}else{
+ throw "This test expects to be run as a Worker";
+}
+
+/* NOT TESTED: setting timeout before calling open( ... , false) in a worker context. The test code always calls open() first. */
+
+runTestRequests([ new RequestTracker(false, "no time out scheduled, load fires normally", 0),
+ new RequestTracker(false, "load fires normally", TIME_NORMAL_LOAD),
+ new RequestTracker(false, "timeout hit before load", TIME_REGULAR_TIMEOUT) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-twice.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-twice.js
new file mode 100644
index 000000000..0061c7333
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-twice.js
@@ -0,0 +1,6 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+
+runTestRequests([ new RequestTracker(true, "load fires normally with no timeout set, twice", 0, TIME_REGULAR_TIMEOUT, 0),
+ new RequestTracker(true, "load fires normally with same timeout set twice", TIME_NORMAL_LOAD, TIME_REGULAR_TIMEOUT, TIME_NORMAL_LOAD),
+ new RequestTracker(true, "timeout fires normally with same timeout set twice", TIME_REGULAR_TIMEOUT, TIME_DELAY, TIME_REGULAR_TIMEOUT) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout.js
new file mode 100644
index 000000000..01e63cde6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout.js
@@ -0,0 +1,325 @@
+/* Test adapted from Alex Vincent's XHR2 timeout tests, written for Mozilla.
+ https://hg.mozilla.org/mozilla-central/file/tip/content/base/test/
+ Released into the public domain or under BSD, according to
+ https://bugzilla.mozilla.org/show_bug.cgi?id=525816#c86
+*/
+
+/* 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 TIME_NORMAL_LOAD = 5000;
+var TIME_LATE_TIMEOUT = 4000;
+var TIME_XHR_LOAD = 3000;
+var TIME_REGULAR_TIMEOUT = 2000;
+var TIME_SYNC_TIMEOUT = 1000;
+var TIME_DELAY = 1000;
+
+/*
+ * This should point to a resource that responds with a text/plain resource after a delay of TIME_XHR_LOAD milliseconds.
+ */
+var STALLED_REQUEST_URL = "delay.py?ms=" + (TIME_XHR_LOAD);
+
+var inWorker = false;
+try {
+ inWorker = !(self instanceof Window);
+} catch (e) {
+ inWorker = true;
+}
+
+if (!inWorker)
+ STALLED_REQUEST_URL = "resources/" + STALLED_REQUEST_URL;
+
+function message(obj) {
+ if (inWorker)
+ self.postMessage(obj);
+ else
+ self.postMessage(obj, "*");
+}
+
+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", STALLED_REQUEST_URL, 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);
+ }
+
+ try {
+ req.send(null);
+ }
+ catch (e) {
+ // Synchronous case in workers.
+ ok(!this.async && this.timeLimit < TIME_XHR_LOAD && e.name == "TimeoutError", "Unexpected error: " + e);
+ TestCounter.testComplete();
+ }
+ },
+
+ /**
+ * 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 TIME_XHR_LOAD milliseconds with a load event.
+ var timeLimit = this.mustReset && (this.resetAfter < Math.min(TIME_XHR_LOAD, this.timeLimit)) ?
+ this.resetTo :
+ this.timeLimit;
+ if ((timeLimit == 0) || (timeLimit >= TIME_XHR_LOAD)) {
+ 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", STALLED_REQUEST_URL);
+ var _this = this;
+ function handleEvent(e) { return _this.handleEvent(e); };
+ req.onerror = handleEvent;
+ req.onload = handleEvent;
+ req.onabort = handleEvent;
+ req.ontimeout = handleEvent;
+
+ req.timeout = TIME_REGULAR_TIMEOUT;
+
+ function abortReq() {
+ req.abort();
+ }
+
+ if (!this.shouldAbort) {
+ self.setTimeout(function() {
+ try {
+ _this.noEventsFired();
+ }
+ catch (e) {
+ ok(false, "Unexpected error: " + e);
+ TestCounter.testComplete();
+ }
+ }, TIME_NORMAL_LOAD);
+ }
+ 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 " + TIME_REGULAR_TIMEOUT;
+ },
+
+ /**
+ * Check the event received, and if it's the right (and only) one we get.
+ *
+ * WebKit fires abort events even for DONE and UNSENT states, which is
+ * discussed in http://webkit.org/b/98404
+ * That's why we chose to accept secondary "abort" events in this test.
+ *
+ * @param {DOMProgressEvent} evt An event of type "load" or "timeout".
+ */
+ handleEvent: function(evt) {
+ if (this.hasFired && evt.type != "abort") {
+ ok(false, "Only abort event should fire: " + this.getMessage());
+ return;
+ }
+
+ var expectedEvent = (this.abortDelay >= TIME_REGULAR_TIMEOUT && !this.hasFired) ? "timeout" : "abort";
+ this.hasFired = true;
+ is(evt.type, expectedEvent, this.getMessage());
+ TestCounter.testComplete();
+ }
+};
+
+var SyncRequestSettingTimeoutAfterOpen = {
+ startXHR: function() {
+ var pass = false;
+ var req = new XMLHttpRequest();
+ req.open("GET", STALLED_REQUEST_URL, false);
+ try {
+ req.timeout = TIME_SYNC_TIMEOUT;
+ }
+ catch (e) {
+ pass = true;
+ }
+ ok(pass, "Synchronous XHR must not allow a timeout to be set - setting timeout must throw");
+ TestCounter.testComplete();
+ }
+};
+
+var SyncRequestSettingTimeoutBeforeOpen = {
+ startXHR: function() {
+ var pass = false;
+ var req = new XMLHttpRequest();
+ req.timeout = TIME_SYNC_TIMEOUT;
+ try {
+ req.open("GET", STALLED_REQUEST_URL, false);
+ }
+ catch (e) {
+ pass = true;
+ }
+ ok(pass, "Synchronous XHR must not allow a timeout to be set - calling open() after timeout is set must throw");
+ TestCounter.testComplete();
+ }
+};
+
+var TestRequests = [];
+
+// 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();
+ }, TIME_NORMAL_LOAD);
+ },
+
+ next: function() {
+ var test = TestRequests.shift();
+
+ if (test) {
+ test.startXHR();
+ }
+ else {
+ message("done");
+ }
+ }
+};
+
+function runTestRequests(testRequests) {
+ TestRequests = testRequests;
+ TestCounter.next();
+}
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/zlib.py b/testing/web-platform/tests/XMLHttpRequest/resources/zlib.py
new file mode 100644
index 000000000..49ed69de7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/zlib.py
@@ -0,0 +1,19 @@
+import zlib
+
+def main(request, response):
+ if "content" in request.GET:
+ output = request.GET["content"]
+ else:
+ output = request.body
+
+ output = zlib.compress(output, 9)
+
+ headers = [("Content-type", "text/plain"),
+ ("Content-Encoding", "deflate"),
+ ("X-Request-Method", request.method),
+ ("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"),
+ ("X-Request-Content-Length", request.headers.get("Content-Length", "NO")),
+ ("X-Request-Content-Type", request.headers.get("Content-Type", "NO")),
+ ("Content-Length", len(output))]
+
+ return headers, output