Create a key pair.
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
-keyout localhost-privkey.pem -out localhost-cert.pem
Run the server.
node index.js
Open https://localhost:8443/ with Firefox.
Create a key pair.
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
-keyout localhost-privkey.pem -out localhost-cert.pem
Run the server.
node index.js
Open https://localhost:8443/ with Firefox.
const http2 = require("http2"); | |
const { HTTP2_HEADER_PATH } = http2.constants; | |
const fs = require("fs"); | |
const SCRIPT = ` | |
function fetchAndSendBeacon(button, beaconPath) { | |
fetch("/slow").then(() => { | |
button.textContent += ": done"; | |
}, () => { | |
button.textContent += ": error"; | |
}); | |
setTimeout(() => { | |
navigator.sendBeacon(beaconPath, "{}"); | |
}, 0); | |
} | |
document.getElementById("without-body").addEventListener("click", (e) => { | |
fetchAndSendBeacon(e.currentTarget, "/beacon-without-body"); | |
}); | |
document.getElementById("with-body").addEventListener("click", (e) => { | |
fetchAndSendBeacon(e.currentTarget, "/beacon-with-body"); | |
}); | |
document.getElementById("with-body-and-delay").addEventListener("click", (e) => { | |
fetchAndSendBeacon(e.currentTarget, "/beacon-with-body-and-delay"); | |
}); | |
document.getElementById("with-double-body").addEventListener("click", (e) => { | |
fetchAndSendBeacon(e.currentTarget, "/beacon-with-double-body"); | |
}); | |
`; | |
const PAGE = `<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf8"> | |
</head> | |
<body> | |
<button id="without-body">Without Body</button> | |
<button id="with-body">With Body</button> | |
<button id="with-body-and-delay">With Body and Delay</button> | |
<button id="with-double-body">With Double Body</button> | |
<script>${SCRIPT}</script> | |
</body> | |
</html> | |
`; | |
function log(...args) { | |
console.log(`\u001b[32m[${new Date().toISOString()}]\u001b[0m`, ...args); | |
} | |
const server = http2.createSecureServer({ | |
key: fs.readFileSync("localhost-privkey.pem"), | |
cert: fs.readFileSync("localhost-cert.pem") | |
}); | |
server.on("error", err => { | |
log("server error", err); | |
}); | |
server.on("session", session => { | |
log("session created"); | |
session.on("error", err => { | |
log("session error:", err); | |
}); | |
session.on("stream", (stream, headers) => { | |
stream.on("error", err => { | |
log("stream error:", err); | |
}); | |
switch (headers[HTTP2_HEADER_PATH]) { | |
case "/": | |
stream.respond({ | |
"content-type": "text/html", | |
":status": 200 | |
}); | |
stream.end(PAGE); | |
break; | |
case "/beacon-without-body": | |
stream.respond({ | |
"content-type": "text/plain", | |
":status": 200 | |
}); | |
stream.end(); | |
break; | |
case "/beacon-with-body": { | |
const body = "Hello World"; | |
stream.respond({ | |
"content-type": "text/plain", | |
"content-length": body.length, | |
":status": 200 | |
}); | |
stream.end(body); | |
break; | |
} | |
case "/beacon-with-body-and-delay": { | |
const body = "Hello World"; | |
stream.respond({ | |
"content-type": "text/plain", | |
"content-length": body.length, | |
":status": 200 | |
}); | |
stream.write(body); | |
// Firefox sends GOAWAY if this delay exists. | |
setTimeout(() => { | |
stream.end(); | |
}, 10); | |
break; | |
} | |
case "/beacon-with-double-body": { | |
const body = "Hello World"; | |
stream.respond({ | |
"content-type": "text/plain", | |
"content-length": body.length * 2, | |
":status": 200 | |
}); | |
stream.write(body); | |
setTimeout(() => { | |
if (!stream.closed) { | |
stream.end(body); | |
} | |
}, 10); | |
break; | |
} | |
case "/slow": | |
setTimeout(() => { | |
if (!stream.closed) { | |
stream.respond({ | |
"content-type": "text/plain", | |
":status": 200 | |
}); | |
stream.end("Hello World"); | |
} | |
}, 500); | |
break; | |
default: | |
stream.respond({ | |
"content-type": "text/html", | |
":status": 401 | |
}); | |
stream.end("<h1>Not found</h1>"); | |
} | |
}); | |
}); | |
server.listen(8443); | |
It was fixed in Nightly! https://bugzilla.mozilla.org/show_bug.cgi?id=1613943