Potential implementation
This commit is contained in:
parent
e65307517d
commit
243d019e8b
1 changed files with 41 additions and 4 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue