Potential implementation

This commit is contained in:
Manav Rathi 2024-04-28 17:24:11 +05:30
parent e65307517d
commit 243d019e8b
No known key found for this signature in database

View file

@ -2,6 +2,7 @@
* @file stream data to-from renderer using a custom protocol handler.
*/
import { net, protocol } from "electron/main";
import StreamZip from "node-stream-zip";
import { createWriteStream, existsSync } from "node:fs";
import fs from "node:fs/promises";
import { Readable } from "node:stream";
@ -34,17 +35,23 @@ export const registerStreamProtocol = () => {
protocol.handle("stream", async (request: Request) => {
const url = request.url;
// The request URL contains the command to run as the host, and the
// pathname of the file as the path. For example,
// pathname of the file as the path. An additional path can be specified
// as the URL hash.
//
// stream://write/path/to/file
// host-pathname-----
// For example,
//
const { host, pathname } = new URL(url);
// stream://write/path/to/file#/path/to/another/file
// host[pathname----] [pathname-2---------]
//
const { host, pathname, hash } = new URL(url);
// Convert e.g. "%20" to spaces.
const path = decodeURIComponent(pathname);
const hashPath = decodeURIComponent(hash);
switch (host) {
case "read":
return handleRead(path);
case "read-zip":
return handleReadZip(path, hashPath);
case "write":
return handleWrite(path, request);
default:
@ -88,6 +95,36 @@ const handleRead = async (path: string) => {
}
};
const handleReadZip = async (zipPath: string, zipEntryPath: string) => {
try {
const zip = new StreamZip.async({
file: zipPath,
});
const entry = await zip.entry(zipEntryPath);
const stream = await zip.stream(entry);
return new Response(Readable.toWeb(new Readable(stream)), {
headers: {
// We don't know the exact type, but it doesn't really matter,
// just set it to a generic binary content-type so that the
// browser doesn't tinker with it thinking of it as text.
"Content-Type": "application/octet-stream",
"Content-Length": `${entry.size}`,
// !!TODO(MR): Is this ms
"X-Last-Modified-Ms": `${entry.time}`,
},
});
} catch (e) {
log.error(
`Failed to read entry ${zipEntryPath} from zip file at ${zipPath}`,
e,
);
return new Response(`Failed to read stream: ${e.message}`, {
status: 500,
});
}
};
const handleWrite = async (path: string, request: Request) => {
try {
await writeStream(path, request.body);