[beacon] Fix ArrayBuffer and URLSearchParams data
`navigator.sendBeacon()` was not handling DOMArrayBuffer and
URLSearchParams inputs properly, resulting in failing WPTs related to
the sent Content-Type, as well as in the wrong data sent in the case
of DOMArrayBuffers.
This CL fixes that.
Bug: 876671
Change-Id: I17674b3041aa0f0bdbd1a570ab34be48b0dd98b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2489986
Commit-Queue: Yoav Weiss <yoavweiss@chromium.org>
Reviewed-by: Adam Rice <ricea@chromium.org>
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#820134}
diff --git a/beacon/headers/header-content-type.html b/beacon/headers/header-content-type-and-body.html
similarity index 61%
rename from beacon/headers/header-content-type.html
rename to beacon/headers/header-content-type-and-body.html
index e2f2705..0369cff 100644
--- a/beacon/headers/header-content-type.html
+++ b/beacon/headers/header-content-type-and-body.html
@@ -12,13 +12,13 @@
<script>
const RESOURCES_DIR = "/beacon/resources/";
-function testContentTypeHeader(what, contentType, title) {
+function testContentTypeAndBody(what, expected, title) {
function wait(ms) {
return new Promise(resolve => step_timeout(resolve, ms));
}
promise_test(async t => {
const id = self.token();
- const testUrl = new Request(RESOURCES_DIR + "content-type.py?cmd=put&id=" + id).url;
+ const testUrl = new Request(RESOURCES_DIR + "content-type-and-body.py?cmd=put&id=" + id).url;
assert_equals(performance.getEntriesByName(testUrl).length, 0);
assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
@@ -26,13 +26,17 @@
await wait(50);
} while (performance.getEntriesByName(testUrl).length === 0);
assert_equals(performance.getEntriesByName(testUrl).length, 1);
- const checkUrl = RESOURCES_DIR + "content-type.py?cmd=get&id=" + id;
+ const checkUrl = RESOURCES_DIR + "content-type-and-body.py?cmd=get&id=" + id;
const response = await fetch(checkUrl);
const text = await response.text();
- if (contentType === "multipart/form-data") {
+ if (expected.startsWith("multipart/form-data")) {
+ const split = expected.split(":");
+ const contentType = split[0];
+ const contentDisposition = "Content-Disposition: form-data; name=\"" + split[1] + "\"; filename=\"blob\"";
assert_true(text.startsWith(contentType), "Correct Content-Type header result");
+ assert_true(text.includes(contentDisposition), "Body included value");
} else {
- assert_equals(text, contentType, "Correct Content-Type header result");
+ assert_equals(text, expected, "Correct Content-Type header result");
}
}, "Test content-type header for a body " + title);
}
@@ -74,12 +78,12 @@
return new URLSearchParams(input);
}
-testContentTypeHeader("hi!", "text/plain;charset=UTF-8", "string");
-testContentTypeHeader(stringToArrayBufferView("123"), "", "ArrayBufferView");
-testContentTypeHeader(stringToArrayBuffer("123"), "", "ArrayBuffer");
-testContentTypeHeader(stringToBlob("123"), "text/plain", "Blob");
-testContentTypeHeader(stringToFormData("qwerty"), "multipart/form-data", "FormData");
-testContentTypeHeader(stringToURLSearchParams("key1=value1&key2=value2"), "application/x-www-form-urlencoded;charset=UTF-8", "URLSearchParams");
+testContentTypeAndBody("hi!", "text/plain;charset=UTF-8: hi!", "string");
+testContentTypeAndBody(stringToArrayBufferView("123"), ": 1\0" + "2\0" + "3\0", "ArrayBufferView");
+testContentTypeAndBody(stringToArrayBuffer("123"), ": 1\0" + "2\0" + "3\0", "ArrayBuffer");
+testContentTypeAndBody(stringToBlob("123"), "text/plain: 123", "Blob");
+testContentTypeAndBody(stringToFormData("qwerty"), "multipart/form-data:qwerty", "FormData");
+testContentTypeAndBody(stringToURLSearchParams("key1=value1&key2=value2"), "application/x-www-form-urlencoded;charset=UTF-8: key1=value1&key2=value2", "URLSearchParams");
</script>
</body>
</html>
diff --git a/beacon/resources/content-type.py b/beacon/resources/content-type-and-body.py
similarity index 92%
rename from beacon/resources/content-type.py
rename to beacon/resources/content-type-and-body.py
index d3be7d4..1c8c4c7 100644
--- a/beacon/resources/content-type.py
+++ b/beacon/resources/content-type-and-body.py
@@ -2,7 +2,7 @@
command = request.GET.first(b"cmd").lower()
test_id = request.GET.first(b"id")
if command == b"put":
- request.server.stash.put(test_id, request.headers.get(b"Content-Type", b""))
+ request.server.stash.put(test_id, request.headers.get(b"Content-Type", b"") + ": " + request.body)
return [(b"Content-Type", b"text/plain")], u""
if command == b"get":