mirror of
https://github.com/servo/servo.git
synced 2025-08-14 18:05:36 +01:00
Update web-platform-tests to revision 346d5b51a122f7bb1c7747064499ef281a0200f7
This commit is contained in:
parent
581c8ba1c8
commit
79b1e6c40c
1728 changed files with 20243 additions and 5349 deletions
|
@ -32,7 +32,17 @@ function checkKoUrl(url, method, desc) {
|
|||
var blob2 = new Blob(["Blob's data"], { "type" : "text/plain" });
|
||||
checkKoUrl("blob:http://{{domains[www]}}:{{ports[http][0]}}/", "GET",
|
||||
"Fetching [GET] blob:http://{{domains[www]}}:{{ports[http][0]}}/ is KO");
|
||||
checkKoUrl(URL.createObjectURL(blob2), "POST",
|
||||
"Fetching [POST] URL.createObjectURL(blob) is KO");
|
||||
|
||||
var invalidRequestMethods = [
|
||||
"POST",
|
||||
"OPTIONS",
|
||||
"HEAD",
|
||||
"PUT",
|
||||
"DELETE",
|
||||
"INVALID",
|
||||
];
|
||||
invalidRequestMethods.forEach(function(method) {
|
||||
checkKoUrl(URL.createObjectURL(blob2), method, "Fetching [" + method + "] URL.createObjectURL(blob) is KO");
|
||||
});
|
||||
|
||||
done();
|
||||
|
|
|
@ -32,7 +32,7 @@ var origin = "http://{{host}}:{{ports[http][0]}}";
|
|||
|
||||
corsPreflightReferrer("Referrer policy: no-referrer", corsUrl, "no-referrer", "");
|
||||
corsPreflightReferrer("Referrer policy: \"\"", corsUrl, "", "");
|
||||
corsPreflightReferrer("Referrer policy: origin-only", corsUrl, "origin-only", origin);
|
||||
corsPreflightReferrer("Referrer policy: origin", corsUrl, "origin", origin);
|
||||
corsPreflightReferrer("Referrer policy: origin-when-cross-origin", corsUrl, "origin-when-cross-origin", origin);
|
||||
corsPreflightReferrer("Referrer policy: unsafe-url", corsUrl, "unsafe-url", location.toString());
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ function corsPreflight(desc, corsUrl, method, allowed, headers) {
|
|||
urlParameters += "&control_request_headers"
|
||||
//Make the server allow the headers
|
||||
urlParameters += "&allow_headers="
|
||||
urlParameters += headers.join("%2C%20");
|
||||
urlParameters += headers.map(function (x) { return x[0]; }).join("%2C%20");
|
||||
}
|
||||
promise_test(function(test) {
|
||||
test.add_cleanup(function() {
|
||||
|
@ -40,8 +40,8 @@ function corsPreflight(desc, corsUrl, method, allowed, headers) {
|
|||
var actualHeaders = resp.headers.get("x-control-request-headers").split(",");
|
||||
for (var i in actualHeaders)
|
||||
actualHeaders[i] = actualHeaders[i].trim();
|
||||
for (var header in headers)
|
||||
assert_in_array(header, actualHeaders, "Preflight asked permission for header: " + header);
|
||||
for (var header of headers)
|
||||
assert_in_array(header[0], actualHeaders, "Preflight asked permission for header: " + header);
|
||||
}
|
||||
});
|
||||
}, desc);
|
||||
|
@ -67,16 +67,13 @@ corsPreflight("CORS [PATCH], server refuses", corsUrl, "PATCH", false);
|
|||
corsPreflight("CORS [NEW], server allows", corsUrl, "NEW", true);
|
||||
corsPreflight("CORS [NEW], server refuses", corsUrl, "NEW", false);
|
||||
|
||||
corsPreflight("CORS [GET] [x-test-header: allowed], server allows", corsUrl, "GET", true, {"x-test-header1": "allowed"});
|
||||
corsPreflight("CORS [GET] [x-test-header: refused], server refuses", corsUrl, "GET", false, {"x-test-header1": "refused"});
|
||||
corsPreflight("CORS [GET] [x-test-header: allowed], server allows", corsUrl, "GET", true, [["x-test-header1", "allowed"]]);
|
||||
corsPreflight("CORS [GET] [x-test-header: refused], server refuses", corsUrl, "GET", false, [["x-test-header1", "refused"]]);
|
||||
|
||||
var headers = {"x-test-header1": "allowedOrRefused",
|
||||
"x-test-header2": "allowedOrRefused",
|
||||
"x-test-header3": "allowedOrRefused",
|
||||
};
|
||||
var headers = [["x-test-header1", "allowedOrRefused"],
|
||||
["x-test-header2", "allowedOrRefused"],
|
||||
["x-test-header3", "allowedOrRefused"]];
|
||||
corsPreflight("CORS [GET] [several headers], server allows", corsUrl, "GET", true, headers);
|
||||
corsPreflight("CORS [GET] [several headers], server refuses", corsUrl, "GET", false, headers);
|
||||
corsPreflight("CORS [PUT] [several headers], server allows", corsUrl, "PUT", true, headers);
|
||||
corsPreflight("CORS [PUT] [several headers], server refuses", corsUrl, "PUT", false, headers);
|
||||
|
||||
done();
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>Fetch: handling different schemes in redirects</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id=log></div>
|
||||
<script>
|
||||
// All non-HTTP(S) schemes cannot survive redirects
|
||||
var url = "../resources/redirect.py?location=",
|
||||
tests = [
|
||||
fetch(url + "mailto:a@a.com"),
|
||||
fetch(url + "data:,HI"),
|
||||
fetch(url + "facetime:a@a.org"),
|
||||
fetch(url + "about:blank"),
|
||||
fetch(url + "about:unicorn"),
|
||||
fetch(url + "blob:djfksfjs")
|
||||
];
|
||||
tests.forEach(function(f) {
|
||||
promise_test(function(t) {
|
||||
return promise_rejects(t, new TypeError(), f)
|
||||
})
|
||||
})
|
||||
</script>
|
|
@ -8,10 +8,58 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/utils.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var now = new Date();
|
||||
/**
|
||||
* Each test is run twice: once using etag/If-None-Match and once with
|
||||
* date/If-Modified-Since. Each test run gets its own URL and randomized
|
||||
* content and operates independently.
|
||||
*
|
||||
* The test steps are run with request_cache.length fetch requests issued
|
||||
* and their immediate results sanity-checked. The cache.py server script
|
||||
* stashes an entry containing any If-None-Match, If-Modified-Since, Pragma,
|
||||
* and Cache-Control observed headers for each request it receives. When
|
||||
* the test fetches have run, this state is retrieved from cache.py and the
|
||||
* expected_* lists are checked, including their length.
|
||||
*
|
||||
* This means that if a request_* fetch is expected to hit the cache and not
|
||||
* touch the network, then there will be no entry for it in the expect_*
|
||||
* lists. AKA (request_cache.length - expected_validation_headers.length)
|
||||
* should equal the number of cache hits that didn't touch the network.
|
||||
*
|
||||
* Test dictionary keys:
|
||||
* - state: required string that determines whether the Expires response for
|
||||
* the fetched document should be set in the future ("fresh") or past
|
||||
* ("stale").
|
||||
* - vary: optional string to be passed to the server for it to quote back
|
||||
* in a Vary header on the response to us.
|
||||
* - cache_control: optional string to be passed to the server for it to
|
||||
* quote back in a Cache-Control header on the response to us.
|
||||
* - redirect: optional string "same-origin" or "cross-origin". If
|
||||
* provided, the server will issue an absolute redirect to the script on
|
||||
* the same or a different origin, as appropriate. The redirected
|
||||
* location is the script with the redirect parameter removed, so the
|
||||
* content/state/etc. will be as if you hadn't specified a redirect.
|
||||
* - request_cache: required array of cache modes to use (via `cache`).
|
||||
* - request_headers: optional array of explicit fetch `headers` arguments.
|
||||
* If provided, the server will log an empty dictionary for each request
|
||||
* instead of the request headers it would normally log.
|
||||
* - response: optional array of specialized response handling. Right now,
|
||||
* "error" array entries indicate a network error response is expected
|
||||
* which will reject with a TypeError.
|
||||
* - expected_validation_headers: required boolean array indicating whether
|
||||
* the server should have seen an If-None-Match/If-Modified-Since header
|
||||
* in the request.
|
||||
* - expected_no_cache_headers: required boolean array indicating whether
|
||||
* the server should have seen Pragma/Cache-control:no-cache headers in
|
||||
* the request.
|
||||
* - expected_max_age_headers: optional boolean array indicating whether
|
||||
* the server should have seen a Cache-Control:max-age=0 header in the
|
||||
* request.
|
||||
*/
|
||||
var tests = [
|
||||
{
|
||||
name: 'RequestCache "default" mode checks the cache for previously cached content and goes to the network for stale responses',
|
||||
|
@ -101,6 +149,62 @@
|
|||
expected_validation_headers: [false],
|
||||
expected_no_cache_headers: [false],
|
||||
},
|
||||
{
|
||||
name: 'RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for stale responses',
|
||||
state: "stale",
|
||||
request_cache: ["default", "only-if-cached"],
|
||||
expected_validation_headers: [false],
|
||||
expected_no_cache_headers: [false]
|
||||
},
|
||||
{
|
||||
name: 'RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses',
|
||||
state: "fresh",
|
||||
request_cache: ["default", "only-if-cached"],
|
||||
expected_validation_headers: [false],
|
||||
expected_no_cache_headers: [false]
|
||||
},
|
||||
{
|
||||
name: 'RequestCache "only-if-cached" mode checks the cache for previously cached content and does not go to the network if a cached response is not found',
|
||||
state: "fresh",
|
||||
request_cache: ["only-if-cached"],
|
||||
response: ["error"],
|
||||
expected_validation_headers: [],
|
||||
expected_no_cache_headers: []
|
||||
},
|
||||
{
|
||||
name: 'RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content',
|
||||
state: "fresh",
|
||||
request_cache: ["default", "only-if-cached"],
|
||||
redirect: "same-origin",
|
||||
expected_validation_headers: [false, false],
|
||||
expected_no_cache_headers: [false, false],
|
||||
},
|
||||
{
|
||||
name: 'RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content',
|
||||
state: "stale",
|
||||
request_cache: ["default", "only-if-cached"],
|
||||
redirect: "same-origin",
|
||||
expected_validation_headers: [false, false],
|
||||
expected_no_cache_headers: [false, false],
|
||||
},
|
||||
{
|
||||
name: 'RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects',
|
||||
state: "fresh",
|
||||
request_cache: ["default", "only-if-cached"],
|
||||
redirect: "cross-origin",
|
||||
response: [null, "error"],
|
||||
expected_validation_headers: [false, false],
|
||||
expected_no_cache_headers: [false, false],
|
||||
},
|
||||
{
|
||||
name: 'RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects',
|
||||
state: "stale",
|
||||
request_cache: ["default", "only-if-cached"],
|
||||
redirect: "cross-origin",
|
||||
response: [null, "error"],
|
||||
expected_validation_headers: [false, false],
|
||||
expected_no_cache_headers: [false, false],
|
||||
},
|
||||
{
|
||||
name: 'RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless',
|
||||
state: "stale",
|
||||
|
@ -348,6 +452,9 @@
|
|||
expected_no_cache_headers: [false, true],
|
||||
},
|
||||
];
|
||||
function base_path() {
|
||||
return location.pathname.replace(/\/[^\/]*$/, '/');
|
||||
}
|
||||
function make_url(uuid, id, value, content, info) {
|
||||
var dates = {
|
||||
fresh: new Date(now.getFullYear() + 1, now.getMonth(), now.getDay()).toGMTString(),
|
||||
|
@ -361,16 +468,36 @@
|
|||
if ("cache_control" in info) {
|
||||
cache_control = "&cache_control=" + info.cache_control;
|
||||
}
|
||||
var redirect = "";
|
||||
|
||||
var ignore_request_headers = "";
|
||||
if ("request_headers" in info) {
|
||||
// Ignore the request headers that we send since they may be synthesized by the test.
|
||||
ignore_request_headers = "&ignore";
|
||||
}
|
||||
return "resources/cache.py?token=" + uuid +
|
||||
"&content=" + content +
|
||||
"&" + id + "=" + value +
|
||||
"&expires=" + dates[info.state] +
|
||||
vary + cache_control + ignore_request_headers;
|
||||
var url_sans_redirect = "resources/cache.py?token=" + uuid +
|
||||
"&content=" + content +
|
||||
"&" + id + "=" + value +
|
||||
"&expires=" + dates[info.state] +
|
||||
vary + cache_control + ignore_request_headers;
|
||||
// If there's a redirect, the target is the script without any redirect at
|
||||
// either the same domain or a different domain.
|
||||
if ("redirect" in info) {
|
||||
var host_info = get_host_info();
|
||||
var origin;
|
||||
switch (info.redirect) {
|
||||
case "same-origin":
|
||||
origin = host_info['HTTP_ORIGIN'];
|
||||
break;
|
||||
case "cross-origin":
|
||||
origin = host_info['HTTP_REMOTE_ORIGIN'];
|
||||
break;
|
||||
}
|
||||
var redirected_url = origin + base_path() + url_sans_redirect;
|
||||
return url_sans_redirect + "&redirect=" + encodeURIComponent(redirected_url);
|
||||
} else {
|
||||
return url_sans_redirect;
|
||||
}
|
||||
}
|
||||
function expected_status(type, identifier, init) {
|
||||
if (type == "date" &&
|
||||
|
@ -395,21 +522,10 @@
|
|||
.then(function(response) {
|
||||
return response.text();
|
||||
}).then(function(text) {
|
||||
return JSON.parse(text);
|
||||
});
|
||||
}
|
||||
function populate_cache(url, content, info, type, identifier) {
|
||||
var init = {cache: info.request_cache[0]};
|
||||
if ("request_headers" in info) {
|
||||
init.headers = info.request_headers[0];
|
||||
}
|
||||
return fetch(url, init)
|
||||
.then(function(response) {
|
||||
assert_array_equals([response.status, response.statusText],
|
||||
expected_status(type, identifier, init));
|
||||
return response.text();
|
||||
}).then(function(text) {
|
||||
assert_equals(text, expected_response_text(type, identifier, init, content));
|
||||
// null will be returned if the server never received any requests
|
||||
// for the given uuid. Normalize that to an empty list consistent
|
||||
// with our representation.
|
||||
return JSON.parse(text) || [];
|
||||
});
|
||||
}
|
||||
function make_test(type, info) {
|
||||
|
@ -418,22 +534,34 @@
|
|||
var identifier = (type == "tag" ? Math.random() : now.toGMTString());
|
||||
var content = Math.random().toString();
|
||||
var url = make_url(uuid, type, identifier, content, info);
|
||||
var fetch_functions = [function() {
|
||||
return populate_cache(url, content, info, type, identifier);
|
||||
}];
|
||||
for (var i = 1; i < info.request_cache.length; ++i) {
|
||||
var fetch_functions = [];
|
||||
for (var i = 0; i < info.request_cache.length; ++i) {
|
||||
fetch_functions.push(function(idx) {
|
||||
var init = {cache: info.request_cache[idx]};
|
||||
if ("request_headers" in info) {
|
||||
init.headers = info.request_headers[idx];
|
||||
}
|
||||
if (init.cache === "only-if-cached") {
|
||||
// only-if-cached requires we use same-origin mode.
|
||||
init.mode = "same-origin";
|
||||
}
|
||||
return fetch(url, init)
|
||||
.then(function(response) {
|
||||
if ("response" in info && info.response[idx] === "error") {
|
||||
assert_true(false, "fetch should have been an error");
|
||||
return;
|
||||
}
|
||||
assert_array_equals([response.status, response.statusText],
|
||||
expected_status(type, identifier, init));
|
||||
return response.text();
|
||||
}).then(function(text) {
|
||||
assert_equals(text, expected_response_text(type, identifier, init, content));
|
||||
}, function(reason) {
|
||||
if ("response" in info && info.response[idx] === "error") {
|
||||
assert_throws(new TypeError(), function() { throw reason; });
|
||||
} else {
|
||||
throw reason;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
var initValuesDict = {"method" : "POST",
|
||||
"referrer" : "http://{{host}}:{{ports[http][0]}}/",
|
||||
"referrerPolicy" : "origin-only",
|
||||
"referrerPolicy" : "origin",
|
||||
"mode" : "same-origin",
|
||||
"credentials" : "include",
|
||||
"cache" : "no-cache",
|
||||
|
@ -28,7 +28,7 @@
|
|||
|
||||
var expectedInitialized = {"method" : "POST",
|
||||
"referrer" : "http://{{host}}:{{ports[http][0]}}/",
|
||||
"referrerPolicy" : "origin-only",
|
||||
"referrerPolicy" : "origin",
|
||||
"mode" : "same-origin",
|
||||
"credentials" : "include",
|
||||
"cache" : "no-cache",
|
||||
|
|
|
@ -62,6 +62,12 @@
|
|||
"Expect TypeError exception");
|
||||
},"RequestInit's mode is no-cors and integrity is not empty");
|
||||
|
||||
test(function() {
|
||||
assert_throws(new TypeError() ,
|
||||
function() { new Request("", {"mode" : "cors", "cache" : "only-if-cached"}); },
|
||||
"Expect TypeError exception");
|
||||
},"RequestInit's cache mode is only-if-cached and mode is not same-origin");
|
||||
|
||||
test(function() {
|
||||
var initialHeaders = new Headers([["Content-Type", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers" : initialHeaders});
|
||||
|
|
|
@ -10,6 +10,7 @@ def main(request, response):
|
|||
expires = request.GET.first("expires", None)
|
||||
vary = request.GET.first("vary", None)
|
||||
cc = request.GET.first("cache_control", None)
|
||||
redirect = request.GET.first("redirect", None)
|
||||
inm = request.headers.get("If-None-Match", None)
|
||||
ims = request.headers.get("If-Modified-Since", None)
|
||||
pragma = request.headers.get("Pragma", None)
|
||||
|
@ -43,8 +44,16 @@ def main(request, response):
|
|||
if cc:
|
||||
response.headers.set("Cache-Control", cc)
|
||||
|
||||
if ((inm is not None and inm == tag) or
|
||||
(ims is not None and ims == date)):
|
||||
# The only-if-cached redirect tests wants CORS to be okay, the other tests
|
||||
# are all same-origin anyways and don't care.
|
||||
response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
|
||||
if redirect:
|
||||
response.headers.set("Location", redirect);
|
||||
response.status = (302, "Redirect")
|
||||
return ""
|
||||
elif ((inm is not None and inm == tag) or
|
||||
(ims is not None and ims == date)):
|
||||
response.status = (304, "Not Modified")
|
||||
return ""
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// This file is duplicated verbatim from:
|
||||
// service-workers/service-worker/resources/get-host-info.sub.js
|
||||
// with the rationale that:
|
||||
// - it's better to not reinvent this
|
||||
// - at the same time, referencing tests deep inside a sibling test group is
|
||||
// not a great idea and copying the file is the lesser evil.
|
||||
function get_host_info() {
|
||||
var ORIGINAL_HOST = '127.0.0.1';
|
||||
var REMOTE_HOST = 'localhost';
|
||||
var UNAUTHENTICATED_HOST = 'example.test';
|
||||
var HTTP_PORT = 8000;
|
||||
var HTTPS_PORT = 8443;
|
||||
try {
|
||||
// In W3C test, we can get the hostname and port number in config.json
|
||||
// using wptserve's built-in pipe.
|
||||
// http://wptserve.readthedocs.org/en/latest/pipes.html#built-in-pipes
|
||||
HTTP_PORT = eval('{{ports[http][0]}}');
|
||||
HTTPS_PORT = eval('{{ports[https][0]}}');
|
||||
ORIGINAL_HOST = eval('\'{{host}}\'');
|
||||
REMOTE_HOST = 'www1.' + ORIGINAL_HOST;
|
||||
} catch (e) {
|
||||
}
|
||||
return {
|
||||
HTTP_ORIGIN: 'http://' + ORIGINAL_HOST + ':' + HTTP_PORT,
|
||||
HTTPS_ORIGIN: 'https://' + ORIGINAL_HOST + ':' + HTTPS_PORT,
|
||||
HTTPS_ORIGIN_WITH_CREDS: 'https://foo:bar@' + ORIGINAL_HOST + ':' + HTTPS_PORT,
|
||||
HTTP_REMOTE_ORIGIN: 'http://' + REMOTE_HOST + ':' + HTTP_PORT,
|
||||
HTTPS_REMOTE_ORIGIN: 'https://' + REMOTE_HOST + ':' + HTTPS_PORT,
|
||||
HTTPS_REMOTE_ORIGIN_WITH_CREDS: 'https://foo:bar@' + REMOTE_HOST + ':' + HTTPS_PORT,
|
||||
UNAUTHENTICATED_ORIGIN: 'http://' + UNAUTHENTICATED_HOST + ':' + HTTP_PORT
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue