Bug 1523562 [wpt PR 14944] - Add tentative WPT to verify download in sandbox, a=testonly

Automatic update from web-platform-tests
Add tentative WPT to verify download in sandbox

General testing idea:
For a network request, we store a token in stash. And after a fixed
period of time sufficient for the download to finish, if there are
any, we validate the token in the stash to see if the network request
was issued and finished successfully.

In the case of <a download> where the decision of download can be made
before resource fetching, the server sets the token immediately.

In the case of navigation to a download, the server will stream a
response over 1 seconds and set the token at the end only when the
socket has been connected. So it is able to detect any download
cancellation while fetching the resource.

Bug: 539938
Change-Id: I734c8cc18d1f761f16646c6b859a6b731ab40ff5
Reviewed-on: https://chromium-review.googlesource.com/c/1422667
Commit-Queue: Yao Xiao <yaoxia@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#626289}

--

wpt-commits: 3b1b4cff2e7078df6d6e1be8bd04e3daf551c727
wpt-pr: 14944
This commit is contained in:
Yao Xiao 2019-02-01 11:40:17 +00:00 коммит произвёл James Graham
Родитель d41cb8008e
Коммит c0c992eea6
6 изменённых файлов: 188 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,31 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>&lt;a download&gt; triggered download in sandbox is allowed by allow-downloads-without-user-activation.</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-iframe-sandbox">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-iframe-element">
<script src="/resources/testharness.js"></script>
<script src='/resources/testharnessreport.js'></script>
<script src="support/iframe_sandbox_download_helper.js"></script>
<body>
<script>
"use strict";
async_test(t => {
const token = "{{$id:uuid()}}";
var iframe = document.createElement("iframe");
iframe.srcdoc = "<a>Download</a>";
iframe.sandbox = "allow-same-origin allow-downloads-without-user-activation";
iframe.onload = t.step_func(function () {
iframe.contentWindow.addEventListener(
"unload", t.unreached_func("Unexpected navigation."));
var anchor = iframe.contentDocument.getElementsByTagName('a')[0];
anchor.href = "support/download_stash.py?token=" + token;
anchor.download = null;
anchor.click();
AssertDownloadSuccess(t, token, DownloadVerifyDelay());
});
document.body.appendChild(iframe);
}, "<a download> triggered download in sandbox is allowed by allow-downloads-without-user-activation.");
</script>
</body>

Просмотреть файл

@ -0,0 +1,31 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>&lt;a download&gt; triggered download in sandbox is blocked.</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-iframe-sandbox">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-iframe-element">
<script src="/resources/testharness.js"></script>
<script src='/resources/testharnessreport.js'></script>
<script src="support/iframe_sandbox_download_helper.js"></script>
<body>
<script>
"use strict";
async_test(t => {
const token = "{{$id:uuid()}}";
var iframe = document.createElement("iframe");
iframe.srcdoc = "<a>Download</a>";
iframe.sandbox = "allow-same-origin";
iframe.onload = t.step_func(function () {
iframe.contentWindow.addEventListener(
"unload", t.unreached_func("Unexpected navigation."));
var anchor = iframe.contentDocument.getElementsByTagName('a')[0];
anchor.href = "support/download_stash.py?token=" + token;
anchor.download = null;
anchor.click();
AssertDownloadFailure(t, token, DownloadVerifyDelay());
});
document.body.appendChild(iframe);
}, "<a download> triggered download in sandbox is blocked.");
</script>
</body>

Просмотреть файл

@ -0,0 +1,33 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Navigation resulted download in sandbox is allowed by allow-downloads-without-user-activation.</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-iframe-sandbox">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-iframe-element">
<script src="/resources/testharness.js"></script>
<script src='/resources/testharnessreport.js'></script>
<script src="support/iframe_sandbox_download_helper.js"></script>
<body>
<script>
"use strict";
async_test(t => {
const token = "{{$id:uuid()}}";
var iframe = document.createElement("iframe");
iframe.srcdoc = "<a>Download</a>";
iframe.sandbox = "allow-same-origin allow-downloads-without-user-activation";
iframe.onload = t.step_func(function () {
iframe.contentWindow.addEventListener(
"unload", t.unreached_func("Unexpected navigation."));
var anchor = iframe.contentDocument.getElementsByTagName('a')[0];
// Set |finish-delay| to let the server stream a response over a period
// of time, so it's able to catch potential download cancellation by
// detecting a socket close.
anchor.href = "support/download_stash.py?token=" + token + "&finish-delay=" + StreamDownloadFinishDelay();
anchor.click();
AssertDownloadSuccess(t, token, StreamDownloadFinishDelay() + DownloadVerifyDelay());
});
document.body.appendChild(iframe);
}, "Navigation resulted download in sandbox is allowed by allow-downloads-without-user-activation.");
</script>
</body>

Просмотреть файл

@ -0,0 +1,33 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Navigation resulted download in sandbox is blocked.</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-iframe-sandbox">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-iframe-element">
<script src="/resources/testharness.js"></script>
<script src='/resources/testharnessreport.js'></script>
<script src="support/iframe_sandbox_download_helper.js"></script>
<body>
<script>
"use strict";
async_test(t => {
const token = "{{$id:uuid()}}";
var iframe = document.createElement("iframe");
iframe.srcdoc = "<a>Download</a>";
iframe.sandbox = "allow-same-origin";
iframe.onload = t.step_func(function () {
iframe.contentWindow.addEventListener(
"unload", t.unreached_func("Unexpected navigation."));
var anchor = iframe.contentDocument.getElementsByTagName('a')[0];
// Set |finish-delay| to let the server stream a response over a period
// of time, so it's able to catch potential download cancellation by
// detecting a socket close.
anchor.href = "support/download_stash.py?token=" + token + "&finish-delay=" + StreamDownloadFinishDelay();
anchor.click();
AssertDownloadFailure(t, token, StreamDownloadFinishDelay() + DownloadVerifyDelay());
});
document.body.appendChild(iframe);
}, "Navigation resulted download in sandbox is blocked.");
</script>
</body>

Просмотреть файл

@ -0,0 +1,28 @@
import time
def main(request, response):
token = request.GET["token"]
response.status = 200
response.headers.append("Content-Type", "text/html")
if "verify-token" in request.GET:
if request.server.stash.take(token):
return 'TOKEN_SET'
return 'TOKEN_NOT_SET'
if "finish-delay" not in request.GET:
# <a download>
request.server.stash.put(token, True)
return
# navigation to download
response.headers.append("Content-Disposition", "attachment")
response.write_status_headers()
finish_delay = float(request.GET["finish-delay"]) / 1E3
count = 10
single_delay = finish_delay / count
for i in range(count): # pylint: disable=unused-variable
time.sleep(single_delay)
response.writer.write_content("\n")
if not response.writer.flush():
return
request.server.stash.put(token, True)

Просмотреть файл

@ -0,0 +1,32 @@
function StreamDownloadFinishDelay() {
return 1000;
}
function DownloadVerifyDelay() {
return 1000;
}
function VerifyDownload(test_obj, token, timeout, expect_download) {
var verify_token = test_obj.step_func(function () {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'support/download_stash.py?verify-token&token=' + token);
xhr.onload = test_obj.step_func(function(e) {
if (expect_download) {
assert_equals(xhr.response, "TOKEN_SET", "Expect download to happen, but got nothing.");
} else {
assert_equals(xhr.response, "TOKEN_NOT_SET", "Expect no download to happen, but got one.");
}
test_obj.done();
});
xhr.send();
});
test_obj.step_timeout(verify_token, timeout);
}
function AssertDownloadSuccess(test_obj, token, timeout) {
VerifyDownload(test_obj, token, timeout, true);
}
function AssertDownloadFailure(test_obj, token, timeout) {
VerifyDownload(test_obj, token, timeout, false);
}