Update web-platform-tests to revision c26470dac73f2df9d4822a0d3482f7eb1ebf57d9

This commit is contained in:
Anthony Ramine 2018-01-10 14:28:20 +01:00
parent 7de87c487b
commit 4d3c932c47
648 changed files with 9014 additions and 4821 deletions

View file

@ -0,0 +1,4 @@
def main(request, response):
return [("Content-Type", "text/plain"),
request.headers.get("Accept-Language", "NO")]

View file

@ -0,0 +1,3 @@
def main(request, response):
return [("Content-Type", "text/plain")], request.headers.get("accept", "NO")

View file

@ -0,0 +1,20 @@
import json
def main(request, response):
if "origin" in request.GET:
response.headers.set("Access-Control-Allow-Origin", request.GET["origin"])
elif "origins" in request.GET:
for origin in request.GET["origins"].split(','):
response.headers.set("Access-Control-Allow-Origin", request.GET["origin"])
if "headers" in request.GET:
response.headers.set("Access-Control-Allow-Headers", request.GET["headers"])
if "methods" in request.GET:
response.headers.set("Access-Control-Allow-Methods", request.GET["methods"])
headers = dict(request.headers)
for header in headers:
headers[header] = headers[header][0]
return json.dumps(headers)

View file

@ -0,0 +1,15 @@
def main(request, response):
headers = {
"Cache-Control": "no-store",
"Access-Control-Allow-Headers": "X-Requested-With",
"Access-Control-Max-Age": 0,
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "*",
"Vary": "Accept-Encoding",
"Content-Type": "text/plain"
}
for (name, value) in headers.items():
response.headers.set(name, value)
response.content = "PASS"

View file

@ -0,0 +1,17 @@
def main(request, response):
response.headers.set("Cache-Control", "no-store")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
response.headers.set("Access-Control-Allow-Credentials", "true")
uid = request.GET.first("uid", None)
if request.method == "OPTIONS":
response.headers.set("Access-Control-Allow-Methods", "PUT")
else:
username = request.auth.username
password = request.auth.password
if (not username) or (username != uid):
response.headers.set("WWW-Authenticate", "Basic realm='Test Realm/Cross Origin'")
response.status = 401
response.content = "Authentication cancelled"
else:
response.content = "User: " + username + ", Password: " + password

View file

@ -0,0 +1,6 @@
#!/usr/bin/env python
def main(request, response):
response.headers.set("Content-Type", "text/plain")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
response.content = "PASS: Cross-domain access allowed."

View file

@ -0,0 +1,6 @@
#!/usr/bin/env python
def main(request, response):
response.headers.set("Content-Type", "text/plain")
response.headers.set("Access-Control-Allow-Origin", "*")
response.content = "PASS: Cross-domain access allowed."

View file

@ -0,0 +1,7 @@
#!/usr/bin/env python
def main(request, response):
response.headers.set("Content-Type", "text/plain")
response.headers.set("Access-Control-Allow-Credentials", "true")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
response.content = "PASS: Cross-domain access allowed."

View file

@ -0,0 +1,14 @@
def main(request, response):
response.headers.set("Cache-Control", "no-store")
# This should be a simple request; deny preflight
if request.method != "POST":
response.status = 400
return
response.headers.set("Access-Control-Allow-Credentials", "true")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
for header in ["Accept", "Accept-Language", "Content-Language", "Content-Type"]:
value = request.headers.get(header)
response.content += header + ": " + (value if value else "<None>") + '\n'

View file

@ -0,0 +1,5 @@
def main(request, response):
response.headers.set("Cache-Control", "no-store")
response.headers.set("Content-Type", "text/plain")
response.text = "FAIL: Cross-domain access allowed."

View file

@ -0,0 +1,9 @@
def main(request, response):
response.headers.set("Cache-Control", "no-store")
# Allow simple requests, but deny preflight
if request.method != "OPTIONS":
response.headers.set("Access-Control-Allow-Credentials", "true")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
else:
response.status = 400

View file

@ -0,0 +1,47 @@
def main(request, response):
def fail(message):
response.content = "FAIL " + request.method + ": " + str(message)
def getState(token):
server_state = request.server.stash.take(token)
if not server_state:
return "Uninitialized"
return server_state
def setState(state, token):
request.server.stash.put(token, state)
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
response.headers.set("Access-Control-Allow-Credentials", "true")
token = request.GET.first("token", None)
state = getState(token)
if state == "Uninitialized":
if request.method == "OPTIONS":
response.headers.set("Access-Control-Allow-Methods", "PUT")
response.headers.set("Access-Control-Max-Age", 10)
setState("OPTIONSSent", token)
else:
fail(state)
elif state == "OPTIONSSent":
if request.method == "PUT":
response.content = "PASS: First PUT request."
setState("FirstPUTSent", token)
else:
fail(state)
elif state == "FirstPUTSent":
if request.method == "OPTIONS":
response.headers.set("Access-Control-Allow-Methods", "PUT, XMETHOD")
response.headers.set("Access-Control-Allow-Headers", "x-test")
setState("SecondOPTIONSSent", token)
elif request.method == "PUT":
fail("Second PUT request sent without preflight")
else:
fail(state)
elif state == "SecondOPTIONSSent":
if request.method == "PUT" or request.method == "XMETHOD":
response.content = "PASS: Second OPTIONS request was sent."
else:
fail(state)
else:
fail(state)

View file

@ -0,0 +1,48 @@
def main(request, response):
def fail(message):
response.content = "FAIL " + request.method + ": " + str(message)
def getState(token):
server_state = request.server.stash.take(token)
if not server_state:
return "Uninitialized"
return server_state
def setState(state, token):
request.server.stash.put(token, state)
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
response.headers.set("Access-Control-Allow-Credentials", "true")
token = request.GET.first("token", None)
state = getState(token)
if state == "Uninitialized":
if request.method == "OPTIONS":
response.headers.set("Access-Control-Allow-Methods", "PUT")
response.headers.set("Access-Control-Allow-Headers", "x-test")
response.headers.set("Access-Control-Max-Age", 1)
setState("OPTIONSSent", token)
else:
fail(state)
elif state == "OPTIONSSent":
if request.method == "PUT":
response.content = "PASS: First PUT request."
setState("FirstPUTSent", token)
else:
fail(state)
elif state == "FirstPUTSent":
if request.method == "OPTIONS":
response.headers.set("Access-Control-Allow-Methods", "PUT")
response.headers.set("Access-Control-Allow-Headers", "x-test")
setState("SecondOPTIONSSent", token)
elif request.method == "PUT":
fail("Second PUT request sent without preflight")
else:
fail(state)
elif state == "SecondOPTIONSSent":
if request.method == "PUT":
response.content = "PASS: Second OPTIONS request was sent."
else:
fail(state)
else:
fail(state)

View file

@ -0,0 +1,47 @@
def main(request, response):
def fail(message):
response.content = "FAIL " + request.method + ": " + str(message)
response.status = 400
def getState(token):
server_state = request.server.stash.take(token)
if not server_state:
return "Uninitialized"
return server_state
def setState(state, token):
request.server.stash.put(token, state)
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
response.headers.set("Access-Control-Allow-Credentials", "true")
token = request.GET.first("token", None)
state = getState(token)
if state == "Uninitialized":
if request.method == "OPTIONS":
response.headers.set("Access-Control-Allow-Methods", "PUT")
response.headers.set("Access-Control-Max-Age", 10)
setState("OPTIONSSent", token)
else:
fail(state)
elif state == "OPTIONSSent":
if request.method == "PUT":
response.content = "PASS: First PUT request."
setState("FirstPUTSent", token)
else:
fail(state)
elif state == "FirstPUTSent":
if request.method == "PUT":
response.content = "PASS: Second PUT request. Preflight worked."
elif request.method == "OPTIONS":
response.headers.set("Access-Control-Allow-Methods", "PUT")
setState("FAILSecondOPTIONSSent", token)
else:
fail(state)
elif state == "FAILSecondOPTIONSSent":
if request.method == "PUT":
fail("Second OPTIONS request was sent. Preflight failed.")
else:
fail(state)
else:
fail(state)

View file

@ -0,0 +1,20 @@
def main(request, response):
if request.method == "OPTIONS":
response.headers.set("Content-Type", "text/plain")
response.headers.set("Access-Control-Allow-Credentials", "true")
response.headers.set("Access-Control-Allow-Methods", "PUT")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
elif request.method == "PUT":
response.headers.set("Content-Type", "text/plain")
response.headers.set("Access-Control-Allow-Credentials", "true")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
response.content = "PASS: Cross-domain access allowed."
try:
response.content += "\n" + request.body
except:
response.content += "Could not read in content."
else:
response.headers.set("Content-Type", "text/plain")
response.content = "Wrong method: " + request.method

View file

@ -0,0 +1,19 @@
def main(request, response):
headers = {
# CORS-safelisted
"content-type": "text/plain",
"cache-control": "no cache",
"content-language": "en",
"expires": "Fri, 30 Oct 1998 14:19:41 GMT",
"last-modified": "Tue, 15 Nov 1994 12:45:26 GMT",
"pragma": "no-cache",
# Non-CORS-safelisted
"x-test": "foobar",
"Access-Control-Allow-Origin": "*"
}
for header in headers:
response.headers.set(header, headers[header])
response.content = "PASS: Cross-domain access allowed."

View file

@ -0,0 +1,16 @@
import datetime
def main(request, response):
cookie_name = request.GET.first("cookie_name", "")
response.headers.set("Cache-Control", "no-store")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
response.headers.set("Access-Control-Allow-Credentials", "true")
for cookie in request.cookies:
# Set cookie to expire yesterday
response.set_cookie(cookie, "deleted", expires=-datetime.timedelta(days=1))
if cookie_name:
# Set cookie to expire tomorrow
response.set_cookie(cookie_name, "COOKIE", expires=datetime.timedelta(days=1))

View file

@ -0,0 +1,9 @@
#!/usr/bin/env python
def main(request, response):
response.headers.set("Content-Type", "text/plain");
response.headers.set("Cache-Control", "no-cache, no-store");
response.headers.set("Access-Control-Allow-External", "true");
response.headers.set("Access-Control-Allow-Origin", "*");
response.content = "PASS: Cross-domain access allowed.\n"
response.content += "HTTP_ORIGIN: " + request.headers.get("origin");

View file

@ -0,0 +1,50 @@
def main(request, response):
def fail(message):
response.content = "FAIL: " + str(message)
response.status = 400
def getState(token):
server_state = request.server.stash.take(token)
if not server_state:
return "Uninitialized"
return server_state
def setState(token, state):
request.server.stash.put(token, state)
def resetState(token):
setState(token, "")
response.headers.set("Cache-Control", "no-store")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
response.headers.set("Access-Control-Max-Age", 1)
token = request.GET.first("token", None)
state = getState(token)
command = request.GET.first("command", None)
if command == "reset":
if request.method == "GET":
resetState(token)
response.content = "Server state reset"
else:
fail("Invalid Method.")
elif state == "Uninitialized":
if request.method == "OPTIONS":
response.content = "This request should not be displayed."
setState(token, "Denied")
else:
fail(state)
elif state == "Denied":
if request.method == "GET" and command == "complete":
resetState(token)
response.content = "Request successfully blocked."
else:
setState("Deny Ignored")
fail("The request was not denied.")
elif state == "Deny Ignored":
resetState(token)
fail(state)
else:
resetState(token)
fail("Unknown Error.")

View file

@ -0,0 +1,16 @@
def main(request, response):
response.headers.set("Cache-Control", "no-store")
response.headers.set("Access-Control-Allow-Origin", "*")
response.headers.set("Access-Control-Max-Age", 0)
if request.method == "OPTIONS":
if "x-test" in [header.strip(" ") for header in
request.headers.get("Access-Control-Request-Headers").split(",")]:
response.headers.set("Access-Control-Allow-Headers", "X-Test")
else:
response.status = 400
elif request.method == "GET":
if request.headers.get("X-Test"):
response.content = "PASS"
else:
response.status = 400

View file

@ -0,0 +1,18 @@
def main(request, response):
response.headers.set('Cache-Control', 'no-store')
response.headers.set('Access-Control-Allow-Origin',
request.headers.get('origin'))
headers = 'x-custom-s,x-custom-test,x-custom-u,x-custom-ua,x-custom-v'
if request.method == 'OPTIONS':
response.headers.set('Access-Control-Max-Age', '0')
response.headers.set('Access-Control-Allow-Headers', headers)
# Access-Control-Request-Headers should be sorted.
if headers != request.headers.get('Access-Control-Request-Headers'):
response.status = 400
else:
if request.headers.get('x-custom-s'):
response.content = 'PASS'
else:
response.status = 400
response.content = 'FAIL'

View file

@ -0,0 +1,12 @@
def main(request, response):
response.headers.set("Cache-Control", "no-store")
response.headers.set("Access-Control-Allow-Origin", "*")
if request.method == "OPTIONS":
if "origin" in request.headers.get("Access-Control-Request-Headers").lower():
response.status = 400
response.content = "Error: 'origin' included in Access-Control-Request-Headers"
else:
response.headers.set("Access-Control-Allow-Headers", "x-pass")
else:
response.content = request.headers.get("x-pass")

View file

@ -0,0 +1,16 @@
def main(request, response):
try:
code = int(request.GET.first("code", None))
except:
code = None
if request.method == "OPTIONS":
if code:
response.status = code
response.headers.set("Access-Control-Max-Age", 1)
response.headers.set("Access-Control-Allow-Headers", "x-pass")
else:
response.status = 200
response.headers.set("Cache-Control", "no-store")
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))

View file

@ -0,0 +1,12 @@
def main(request, response):
if request.method == "OPTIONS" and request.cookies.get("foo"):
response.status = 400
else:
response.headers.set("Cache-Control", "no-store")
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-Headers", "X-Proprietary-Header")
response.headers.set("Connection", "close")
if request.cookies.get("foo"):
response.content = request.cookies["foo"].value

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
window.addEventListener("message", (evt) => {
const url = evt.data;
const xhr = new XMLHttpRequest;
xhr.open("GET", url, false);
try {
xhr.send();
} catch(e) {
parent.postMessage("Exception thrown. Sandboxed iframe XHR access was denied in 'send'.", "*");
return;
}
parent.postMessage(xhr.responseText, "*");
}, false);
parent.postMessage("ready", "*");
</script>
</body>
</html>

View file

@ -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)

View file

@ -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)

View file

@ -0,0 +1,17 @@
import imp
import os
here = os.path.dirname(__file__)
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.abspath(os.path.join(here, os.pardir, "authentication.py")))
if request.method == "OPTIONS":
return ""
else:
return auth.main(request, response)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,21 @@
import imp
import os
here = os.path.dirname(__file__)
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(here,
os.pardir,
"authentication.py"))
if request.method == "OPTIONS":
return ""
else:
return auth.main(request, response)

View file

@ -0,0 +1,22 @@
import imp
import os
here = os.path.dirname(__file__)
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(here,
os.pardir,
"authentication.py"))
if request.method == "OPTIONS":
return ""
else:
return auth.main(request, response)

View file

@ -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)

View file

@ -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;

View file

@ -0,0 +1 @@
<base xmlns="http://www.w3.org/1999/xhtml" href="https://example.com/"/>

View file

@ -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")

View file

@ -0,0 +1,29 @@
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)
cors = request.GET.first("cors", None)
if request.method == "OPTIONS":
response.headers.set("Access-Control-Allow-Origin", "*")
response.headers.set("Access-Control-Allow-Headers", "IF-NONE-MATCH")
return ""
if tag:
response.headers.set("ETag", '"%s"' % tag)
elif date:
response.headers.set("Last-Modified", date)
if cors:
response.headers.set("Access-Control-Allow-Origin", "*")
if ((match is not None and match == tag) or
(modified is not None and modified == date)):
response.status = (304, "SUPERCOOL")
return ""
else:
if not cors:
response.headers.set("Access-Control-Allow-Origin", "*")
response.headers.set("Content-Type", "text/plain")
return "MAYBE NOT"

View file

@ -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

View file

@ -0,0 +1,23 @@
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)
if "safelist_content_type" in request.GET:
headers.append(("Access-Control-Allow-Headers", "content-type"))
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"

View file

@ -0,0 +1,7 @@
import time
def main(request, response):
delay = float(request.GET.first("ms", 500))
time.sleep(delay / 1E3);
return [("Access-Control-Allow-Origin", "*"), ("Access-Control-Allow-Methods", "YO"), ("Content-type", "text/plain")], "TEST_DELAY"

View file

@ -0,0 +1,6 @@
def main(request, response):
response.writer.write_status(200)
response.writer.write_header("Content-Type", "text/plain")
response.writer.end_headers()
response.writer.write(str(request.raw_headers))
response.close_connection = True

View file

@ -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

View file

@ -0,0 +1,5 @@
def main(request, response):
headers = [("Content-type", "text/html;charset=utf-8")]
content = "<!DOCTYPE html><div></div>"
return headers, content

View file

@ -0,0 +1 @@
bottom

View file

@ -0,0 +1,2 @@
def main(request, response):
return "id:%s;value:%s;" % (request.POST.first("id"), request.POST.first("value"))

View file

@ -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

View file

@ -0,0 +1,2 @@
HTTP/1.0 200 NANANA
CONTENT-LENGTH: 0

View file

@ -0,0 +1,4 @@
HTTP/1.1 280 HELLO
foo-test: 1
foo-test: 2
foo-test: 3

View file

@ -0,0 +1,5 @@
HTTP/1.1 200 YAYAYAYA
foo-TEST: 1
FOO-test: 2
ALSO-here: Mr. PB
ewok: lego

View file

@ -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"

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

View file

@ -0,0 +1,5 @@
def main(request, response):
headers = [("Content-type", "text/html;charset=utf-8")]
content = "<img>foo"
return headers, content

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View file

@ -0,0 +1,22 @@
def main(request, response):
location = "%s://%s%s" % (request.url_parts.scheme,
request.url_parts.netloc,
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

View file

@ -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>

View file

@ -0,0 +1,35 @@
def get_response(raw_headers, filter_value, filter_name):
result = ""
for line in raw_headers.headers:
if line[-2:] != '\r\n':
return "Syntax error: missing CRLF: " + line
line = line[:-2]
if ':' not in line:
return "Syntax error: no colon found: " + line
name, value = line.split(':', 1)
if len(value) > 1 and value[0] == ' ':
value = value[1:]
if filter_value:
if value == filter_value:
result += name + ","
elif name.lower() == filter_name:
result += name + ": " + value + "\n";
return result
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"))
headers.append(("content-type", "text/plain"))
filter_value = request.GET.first("filter_value", "")
filter_name = request.GET.first("filter_name", "").lower()
result = get_response(request.raw_headers, filter_value, filter_name)
return headers, result

View file

@ -0,0 +1,5 @@
def main(request, response):
headers = [("Content-type", "text/html;charset=utf-8")]
content = chr(0xff)
return headers, content

View file

@ -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()

View file

@ -0,0 +1,27 @@
def main(request, response):
def getState(token):
server_state = request.server.stash.take(token)
if not server_state:
return "Uninitialized"
return server_state
def setState(state, token):
request.server.stash.put(token, state)
response.headers.set("Access-Control-Allow-Origin", "*")
response.headers.set("Access-Control-Allow-Headers", "x-test")
response.headers.set("Access-Control-Max-Age", 0)
token = request.GET.first("token", None)
if request.method == "OPTIONS":
if request.headers.get("x-test"):
response.content = "FAIL: Invalid header in preflight request."
response.status = 400
else:
setState("PASS", token)
else:
if request.headers.get("x-test"):
response.content = getState(token)
else:
response.content = "FAIL: X-Test header missing in request"
response.status = 400

View file

@ -0,0 +1 @@
not CORS-enabled

View file

@ -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

View file

@ -0,0 +1 @@
PASS

View file

@ -0,0 +1,20 @@
def main(request, response):
location = request.GET.first("location")
if request.method == "OPTIONS":
if "redirect_preflight" in request.GET:
response.status = 302
response.headers.set("Location", location)
else:
response.status = 200
response.headers.set("Access-Control-Allow-Methods", "GET")
response.headers.set("Access-Control-Max-Age", 1)
elif request.method == "GET":
response.status = 302
response.headers.set("Location", location)
if "allow_origin" in request.GET:
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
if "allow_header" in request.GET:
response.headers.set("Access-Control-Allow-Headers", request.GET.first("allow_header"))

View file

@ -0,0 +1,14 @@
import time
def main(request, response):
code = int(request.GET.first("code", 302))
location = request.GET.first("location", request.url_parts.path +"?followed")
if "delay" in request.GET:
delay = float(request.GET.first("delay"))
time.sleep(delay / 1E3);
if "followed" in request.GET:
return [("Content:Type", "text/plain")], "MAGIC HAPPENED"
else:
return (code, "WEBSRT MARKETING"), [("Location", location)], "TEST"

View file

@ -0,0 +1,6 @@
def main(request, response):
if "full" in request.GET:
return request.url
else:
return request.request_path

View file

@ -0,0 +1,5 @@
def main(request, response):
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin"))
token = request.GET["token"]
request.server.stash.put(token, "")
response.content = "PASS"

View file

@ -0,0 +1,9 @@
self.importScripts('/resources/testharness.js');
test(function() {
let xhr = new XMLHttpRequest();
xhr.responseType = "document";
assert_not_equals(xhr.responseType, "document");
}, "Setting XMLHttpRequest responseType to 'document' in a worker should have no effect.");
done();

View file

@ -0,0 +1,9 @@
self.importScripts('/resources/testharness.js');
test(function() {
let xhr = new XMLHttpRequest();
assert_not_exists(xhr, "responseXML", "responseXML should not be available on instances.");
assert_not_exists(XMLHttpRequest.prototype, "responseXML", "responseXML should not be on the prototype.");
}, "XMLHttpRequest's responseXML property should not be exposed in workers.");
done();

View file

@ -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>

View file

@ -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>

View file

@ -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, "*");
}

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

Binary file not shown.

View file

@ -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>

View file

@ -0,0 +1,5 @@
def main(request, response):
headers = [("Content-type", "text/html;charset=windows-1252")]
content = chr(0xff)
return headers, content

View file

@ -0,0 +1,5 @@
def main(request, response):
headers = [("Content-type", "application/xml;charset=windows-1252")]
content = '<' + chr(0xff) + '/>'
return headers, content

View file

@ -0,0 +1,63 @@
importScripts("/resources/testharness.js")
async_test(function() {
var expected = 'Referer: ' +
location.href.replace(/[^/]*$/, '') +
"workerxhr-origin-referrer.js\n"
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = this.step_func(function() {
if (xhr.readyState == 4) {
assert_equals(xhr.responseText, expected)
this.done()
}
})
xhr.open('GET', 'inspect-headers.py?filter_name=referer', true)
xhr.send()
}, 'Referer header')
async_test(function() {
var expected = 'Origin: ' +
location.protocol +
'//' +
location.hostname +
(location.port === "" ? "" : ":" + location.port) +
'\n'
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = this.step_func(function() {
if (xhr.readyState == 4) {
assert_equals(xhr.responseText, expected)
this.done()
}
})
var url = location.protocol +
'//www2.' +
location.hostname +
(location.port === "" ? "" : ":" + location.port) +
location.pathname.replace(/[^/]*$/, '') +
'inspect-headers.py?filter_name=origin&cors'
xhr.open('GET', url, true)
xhr.send()
}, 'Origin header')
async_test(function() {
// 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 expected = location.href.replace(/[^/]*$/, '') +
'requri.py?full'
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = this.step_func(function() {
if (xhr.readyState == 4) {
assert_equals(xhr.responseText, expected)
this.done()
}
})
xhr.open('GET', 'requri.py?full', true)
xhr.send()
}, 'Request URL test')
done()

View file

@ -0,0 +1,9 @@
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()

View file

@ -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));

View file

@ -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) ]);

View file

@ -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) ]);

View file

@ -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) ]);

View file

@ -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) ]);

View file

@ -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 });

View file

@ -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) ]);

View file

@ -0,0 +1,2 @@
runTestRequests([ SyncRequestSettingTimeoutAfterOpen,
SyncRequestSettingTimeoutBeforeOpen ]);

View file

@ -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) ]);

View file

@ -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) ]);

View file

@ -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();
}

View file

@ -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