Skip to content

Instantly share code, notes, and snippets.

@mnvr
Created April 16, 2024 08:19
Show Gist options
  • Save mnvr/e08d9f4876fb8400b7615347b4d268eb to your computer and use it in GitHub Desktop.
Save mnvr/e08d9f4876fb8400b7615347b4d268eb to your computer and use it in GitHub Desktop.
Electron Fiddle to demonstrate malformed streams with Electron 30.x etc. Send always works (shasum /tmp/myscheme.txt = d269175ac71ed60bb96f08881c39453c8e8d7020). Stream doesn't. Uncommenting the wait makes the stream also work.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<!-- <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"> -->
<title>Stream</title>
</head>
<body>
<button id="send">Send</button><br/>
<button id="stream">Stream</button>
<script src="./renderer.js"></script>
</body>
</html>
const { app, protocol, BrowserWindow } = require("electron");
const fs = require("node:fs/promises");
protocol.registerSchemesAsPrivileged([
{
scheme: "myscheme",
privileges: {
standard: true,
secure: true,
supportFetchAPI: true,
corsEnabled: true,
},
},
]);
app.whenReady().then(() => {
const win = new BrowserWindow();
win.loadFile("index.html");
win.webContents.openDevTools();
protocol.handle("myscheme", async (request) => {
console.log("incoming request");
try {
await fs.rm("/tmp/myscheme.txt");
} catch {}
for await (const p of request.body) {
console.log(`got ${p.length} bytes`);
await fs.appendFile("/tmp/myscheme.txt", p);
}
console.log("done");
return new Response("", { status: 200 });
});
});
const dataStream = () =>
new ReadableStream({
async start(controller) {
for (let i = 0; i < 10; i++) {
// await wait(1000);
controller.enqueue(Array(1024 * 128).fill(+i).join("\n"));
}
controller.close();
},
}).pipeThrough(new TextEncoderStream());
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const send = async () => {
const data = new Uint8Array(await new Response(dataStream()).arrayBuffer());
return fetch(
new Request("myscheme://host", {
method: "POST",
body: data,
})
);
};
const stream = () =>
fetch(
new Request("myscheme://host", {
method: "POST",
body: dataStream(),
duplex: "half",
})
);
document.querySelector("#send").addEventListener("click", send);
document.querySelector("#stream").addEventListener("click", stream);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment