diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /testing/web-platform/tests/XMLHttpRequest/resources | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-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')
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 Binary files differnew file mode 100644 index 000000000..6d1174af1 --- /dev/null +++ b/testing/web-platform/tests/XMLHttpRequest/resources/image.gif 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 Binary files differnew file mode 100644 index 000000000..7aa936252 --- /dev/null +++ b/testing/web-platform/tests/XMLHttpRequest/resources/img.jpg 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 Binary files differnew file mode 100644 index 000000000..0085dfaee --- /dev/null +++ b/testing/web-platform/tests/XMLHttpRequest/resources/utf16.txt 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="n1">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 |