Skip to content

Commit

Permalink
Bug 1647892 - Improve the reliability of test_double_submit.html, r=f…
Browse files Browse the repository at this point in the history
…arre

Unlike the previous implementation, this new version performs the
waiting before sending response headers, meaning that it delays
OnStartRequest rather than just delaying the response body. As the
double-submission prevention currently only waits for OnStartRequest,
this should improve the reliability of the test.

Because the test no longer requires large amounts of data for delay
purposes, it has also been simplified to not generate random large
payloads anymore.

Differential Revision: https://phabricator.services.mozilla.com/D141427
  • Loading branch information
mystor committed Mar 21, 2022
1 parent bff3423 commit 07dabb3
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 86 deletions.
97 changes: 23 additions & 74 deletions docshell/test/mochitest/double_submit.sjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,10 @@ const BinaryInputStream = CC(
"setInputStream"
);

const BinaryOutputStream = CC(
"@mozilla.org/binaryoutputstream;1",
"nsIBinaryOutputStream",
"setOutputStream"
);

function log(str) {
// dump(`LOG: ${str}\n`);
}

function* generateBody(fragments, size) {
let result = [];
let chunkSize = (size / fragments) | 0;
let remaining = size;

log(`Chunk size ${chunkSize}`);
while (remaining > 0) {
let data = new Uint8Array(Math.min(remaining, chunkSize));
for (let i = 0; i < data.length; ++i) {
// Generate a character in the [a-z] range.
data[i] = 97 + Math.random() * (123 - 97);
}

yield data;
log(`Remaining to chunk ${remaining}`);
remaining -= data.length;
}
}

function readStream(inputStream) {
let available = 0;
let result = [];
Expand All @@ -60,9 +35,9 @@ async function handleRequest(request, response) {
Cu.importGlobalProperties(["URLSearchParams"]);
let params = new URLSearchParams(request.queryString);

let start = now();
let delay = parseInt(params.get("delay")) || 0;
let delayUntil = now() + delay;
log(`Delay until ${delayUntil}`);
log(`Delay for ${delay}`);

let message = "good";
if (request.method !== "POST") {
Expand All @@ -76,54 +51,28 @@ async function handleRequest(request, response) {
log(`The result was ${message}`);
}

let fragments = parseInt(params.get("fragments")) || 1;
let size = parseInt(params.get("size")) || 1024;

let outputStream = new BinaryOutputStream(response.bodyOutputStream);

let header = "<!doctype html><!-- ";
let footer = ` --><script>"use strict"; let target = (opener || parent); target.postMessage('${message}', '*');</script>`;

log("Set headers");
response.setHeader("Content-Type", "text/html", false);
response.setHeader(
"Content-Length",
`${size + header.length + footer.length}`,
false
);
response.setStatusLine(request.httpVersion, "200", "OK");

response.processAsync();
log("Write header");
response.write(header);
log("Write body");
for (let data of generateBody(fragments, size)) {
delay = Math.max(0, delayUntil - now());
log(`Delay sending fragment for ${delay / fragments}`);
let failed = false;
await new Promise(resolve => {
setTimeout(() => {
try {
outputStream.writeByteArray(data, data.length);
} catch (e) {
log(e.message);
failed = true;
}
resolve();
}, delay / fragments);
});

if (failed) {
log("Stopped sending data");
break;
}

fragments = Math.max(--fragments, 1);
log(`Fragments left ${fragments}`);
}
let body = `<!doctype html>
<script>
"use strict";
let target = (opener || parent);
target.postMessage(${JSON.stringify(message)}, '*');
</script>`;

// Sieze power from the response to allow manually transmitting data at any
// rate we want, so we can delay transmitting headers.
response.seizePower();

log("Write footer");
response.write(footer);
log(`Writing HTTP status line at ${now() - start}`);
response.write("HTTP/1.1 200 OK\r\n");

await new Promise(resolve => setTimeout(() => resolve(), delay));

log(`Delay completed at ${now() - start}`);
response.write("Content-Type: text/html\r\n");
response.write(`Content-Length: ${body.length}\r\n`);
response.write("\r\n");
response.write(body);
response.finish();

log("Finished");
}
13 changes: 1 addition & 12 deletions docshell/test/mochitest/test_double_submit.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
</head>
<body>
<iframe name="targetFrame" id="targetFrame"></iframe>
<form id="form" action="double_submit.sjs?size=4096&fragments=10&delay=1000" method="POST" target="targetFrame">
<input id="input" type="text" name="text" value="value">
<form id="form" action="double_submit.sjs?delay=1000" method="POST" target="targetFrame">
<input id="token" type="text" name="token" value="">
<input id="button" type="submit">
</form>
Expand All @@ -18,15 +17,6 @@

const CROSS_ORIGIN_URI = "http://test1.example.com/tests/docshell/test/mochitest/ping.html";

function generateBody(size) {
let data = new Uint8Array(size);
for (let i = 0; i < size; ++i) {
data[i] = 97 + Math.random() * (123 - 97);
}

return new TextDecoder().decode(data);
}

function asyncClick(counts) {
let frame = document.createElement('iframe');
frame.addEventListener(
Expand Down Expand Up @@ -59,7 +49,6 @@
let form = document.getElementById('form');
let button = document.getElementById('button');

document.getElementById('input').value = generateBody(1024*1024);
let token = document.getElementById('token');
token.value = "first";

Expand Down

0 comments on commit 07dabb3

Please sign in to comment.