Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /fetch/api/request/request-keepalive-quota.html?include=keepalive-request-different-origins-1 - WPT Dashboard Interop Dashboard
- /fetch/api/request/request-keepalive-quota.html?include=keepalive-request-limit-per-origin-1 - WPT Dashboard Interop Dashboard
- /fetch/api/request/request-keepalive-quota.html?include=keepalive-request-limit-per-origin-2 - WPT Dashboard Interop Dashboard
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Request Keepalive Quota Per Origin Tests</title>
<meta name="timeout" content="long">
<meta name="author" title="Sunil Mayya" href="mailto:smayya@mozilla.com">
<meta name="variant" content="?include=keepalive-request-limit-per-origin-1">
<meta name="variant" content="?include=keepalive-request-limit-per-origin-2">
<meta name="variant" content="?include=keepalive-request-different-origins-1">
<meta name=" variant" content="?include=keepalive-request-different-origins-2">
<script src="/common/get-host-info.sub.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/subset-tests-by-key.js"></script>
<script src="/fetch/api/resources/keepalive-helper.js"></script>
<script>
// These tests verify resource limits specific to firefox
// We verify the following:
// 1. Blocking New Keep-Alive Requests (keepalive-request-limit-per-origin-1):
// Firefox should block sending new keep-alive requests if the pending keep-alive request
// quota per origin is reached.
// 2. Releasing Quota (keepalive-request-limit-per-origin-2):
// Firefox should be able to send new keep-alive requests once the quota per origin
// becomes available (i.e., all pending keep-alive requests are resolved).
// 3. Different Origin Requests (keepalive-request-different-origins-1):
// If the keep-alive quota of one origin is full, Firefox should allow new keep-alive
// requests from a different origin.
// 4. Total Requests Per Browser Instance (keepalive-request-different-origins-2):
// Verify that the total number of keep-alive requests per browser instance is limited
// by sending keep-alive requests from different origins.
// The remote origin URL is used to create keep-alive requests from a different origin.
// keepalive-requests.html'creates 5 keepalive pending requests from a remote origin.
const trickleRemoteURL = get_host_info().HTTPS_REMOTE_ORIGIN + '/_mozilla/fetch/api/request/resources/keepalive-requests.html';
const noDelay = 0;
const standardDelay = 1000;
// Starts a request from a different origin, a new tab is opened and
// we load the page hosted on a different origin than request-keepalive-quota.html.
function fetchKeepAliveRequestRemoteUrl(url) {
return new Promise((resolve, reject) => {
try {
var w = window.open(url, '_blank');
if (!w) {
reject(new Error('Failed to open the new window'));
}
window.addEventListener('message', function listener() {
if (event.data === "REQUEST SENT") {
// we have successfully created 5 keepalive requests in the new tab
window.removeEventListener('message', listener);
resolve();
} else if (event.data === "FAIL") {
window.removeEventListener('message', listener);
reject(new Error('Fetch request failed'));
}
});
} catch (error) {
reject(error);
}
});
}
</script>
</head>
<body>
<script>
'use strict';
// Ensure we restrict the number of pending requests per origin.
subsetTestByKey("keepalive-request-limit-per-origin-1", promise_test, function (test) {
SpecialPowers.setIntPref("dom.fetchKeepalive.request_limit_per_origin", 4);
const first = createPendingKeepAliveRequest(standardDelay * 2);
const second = createPendingKeepAliveRequest(standardDelay * 2);
const third = createPendingKeepAliveRequest(standardDelay * 2);
const fourth = createPendingKeepAliveRequest(standardDelay * 2);
const fifth = createPendingKeepAliveRequest(noDelay).then(
() => {
return Promise.reject("A Keepalive fetch() should be rejected when per origin pending requests exceed the limit.");
},
() => {
return Promise.resolve();
});
return Promise.all([first, second, third, fourth, fifth]);
}, 'Restrict the number of pending requests per origin to dom.fetchKeepalive.request_limit_per_origin');
// Ensure keepalive requests per origin quota becomes available after pending requests are completed.
subsetTestByKey("keepalive-request-limit-per-origin-2", promise_test, function (test) {
SpecialPowers.setIntPref("dom.fetchKeepalive.request_limit_per_origin", 2);
const first = createPendingKeepAliveRequest(standardDelay * 2);
const second = createPendingKeepAliveRequest(standardDelay * 2).then(() => {
// ensure that we can send another Keep-Alive fetch after pending requests are completed.
return createPendingKeepAliveRequest(noDelay);
});
const third = createPendingKeepAliveRequest(noDelay).then(() => {
return Promise.reject("A Keep-Alive fetch() request exceeding per origin limit should reject.");
}, () => {
return Promise.resolve();
});
return Promise.all([first, second, third]);
}, 'A Keep-Alive fetch() per origin quota should become available after pending requests are completed.');
// Ensure keepalive limits of different origins do not affect each other.
subsetTestByKey("keepalive-request-different-origins-1", promise_test, function (test) {
SpecialPowers.setIntPref("dom.fetchKeepalive.request_limit_per_origin", 5);
SpecialPowers.setIntPref("dom.fetchKeepalive.total_request_limit", 7);
// fetchKeepAliveRequestRemoteUrl creates 5 pending keepalive requests from a remote origin
const first = fetchKeepAliveRequestRemoteUrl(trickleRemoteURL).then(() => {
// ensure that when remote origin has reached full quota,
// we are still able to send keepalive requests from the current window.
const second = createPendingKeepAliveRequest(standardDelay);
const third = createPendingKeepAliveRequest(noDelay).then(() => {
return new Promise((resolve, reject) => {
try {
// By now we have 5 pending requests from the remote origin.
// Add event listener to ensure these pending requests are completed
window.addEventListener('message', function listener() {
// remote origin has successfully completed keepalive requests
if (event.data === "REQUEST COMPLETED") {
resolve();
window.removeEventListener('message', listener);
} else if (event.data === "FAIL") {
reject(new Error('Fetch request failed'));
window.removeEventListener('message', listener);
}
});
} catch (error) {
send
reject(error);
}
});
});
return Promise.all([second, third]);
}).catch((error) => {
return Promise.reject(error);
});
return first;
}, 'keepalive limits of different origins should not affect each other');
// Ensure that total keepalive request limits are respected
subsetTestByKey("keepalive-request-different-origins-2", promise_test, function (test) {
SpecialPowers.setIntPref("dom.fetchKeepalive.request_limit_per_origin", 5);
SpecialPowers.setIntPref("dom.fetchKeepalive.total_request_limit", 6);
// creates 5 pending keepalive requests for a different origin
const first = fetchKeepAliveRequestRemoteUrl(trickleRemoteURL).then(() => {
// ensure that when remote origin has reached full quota,
// we are still able to send exactly 1 keepalive request for the current origin.
const second = createPendingKeepAliveRequest(standardDelay);
const third = createPendingKeepAliveRequest(noDelay).then(
() => {
return Promise.reject("A Keep-Alive fetch() request exceeding total limit should be rejected.");
},
() => {
return new Promise((resolve, reject) => {
try {
window.addEventListener('message', function listener() {
// remote origin has successfully completed keepalive requests
if (event.data === "REQUEST COMPLETED") {
resolve();
window.removeEventListener('message', listener);
} else if (event.data === "FAIL") {
reject(new Error('Fetch request failed'));
window.removeEventListener('message', listener);
}
});
} catch (error) {
reject(error);
}
});
});
return Promise.all([second, third]);
}).catch((error) => {
return Promise.reject(error);
});
return first;
}, 'total keepalive request limits should be respected');
</script>
</body>
</html>