Content-Length

This commit is contained in:
Manav Rathi 2024-04-23 12:35:22 +05:30
parent cb0d25030d
commit e6e235490a
No known key found for this signature in database
2 changed files with 38 additions and 20 deletions

View file

@ -44,33 +44,49 @@ export const registerStreamProtocol = () => {
const path = decodeURIComponent(pathname);
switch (host) {
case "read":
try {
return net.fetch(pathToFileURL(path).toString());
} catch (e) {
log.error(`Failed to read stream for ${url}`, e);
return new Response(`Failed to read stream: ${e.message}`, {
status: 500,
});
}
return handleRead(path);
case "write":
try {
await writeStream(path, request.body);
return new Response("", { status: 200 });
} catch (e) {
log.error(`Failed to write stream for ${url}`, e);
return new Response(
`Failed to write stream: ${e.message}`,
{ status: 500 },
);
}
return handleWrite(path, request);
default:
return new Response("", { status: 404 });
}
});
};
const handleRead = async (path: string) => {
try {
const res = await net.fetch(pathToFileURL(path).toString());
if (res.ok) {
// net.fetch defaults to text/plain, which might be fine
// in practice, but as an extra precaution indicate that
// this is binary data.
res.headers.set("Content-Type", "application/octet-stream");
// Add the file's size as the Content-Length header.
const fileSize = (await fs.stat(path)).size;
res.headers.set("Content-Length", `${fileSize}`);
}
return res;
} catch (e) {
log.error(`Failed to read stream at ${path}`, 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);
return new Response("", { status: 200 });
} catch (e) {
log.error(`Failed to write stream to ${path}`, e);
return new Response(`Failed to write stream: ${e.message}`, {
status: 500,
});
}
};
/**
* Write a (web) ReadableStream to a file at the given {@link filePath}.
*

View file

@ -17,6 +17,8 @@
* @return A standard web {@link Response} object that contains the contents of
* the file. In particular, `response.body` will be a {@link ReadableStream}
* that can be used to read the files contents in a streaming, chunked, manner.
* Also, the response is guaranteed to have a "Content-Length" header indicating
* the size of the file that we'll be reading from disk.
*/
export const readStream = async (path: string) => {
const req = new Request(`stream://read${path}`, {