Initial commit
This commit is contained in:
72
server/api/drops/[id]/chunks/[index].get.ts
Normal file
72
server/api/drops/[id]/chunks/[index].get.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import {
|
||||
createError,
|
||||
defineEventHandler,
|
||||
getRouterParam,
|
||||
sendStream,
|
||||
setHeaders,
|
||||
} from "h3";
|
||||
import { dropStore, DropStoreError } from "../../../../utils/drop-store";
|
||||
import { bearerToken, publicHeaders } from "../../../../utils/http";
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
publicHeaders(event);
|
||||
const token = bearerToken(event);
|
||||
if (!token)
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: "A valid lease is required.",
|
||||
});
|
||||
const id = String(getRouterParam(event, "id") || "").toUpperCase();
|
||||
let handle:
|
||||
| Awaited<ReturnType<typeof dropStore.readChunk>>["handle"]
|
||||
| undefined;
|
||||
let stream:
|
||||
| ReturnType<NonNullable<typeof handle>["createReadStream"]>
|
||||
| undefined;
|
||||
let closed = false;
|
||||
const close = async () => {
|
||||
if (closed) return;
|
||||
closed = true;
|
||||
stream?.destroy();
|
||||
await handle?.close().catch(() => undefined);
|
||||
};
|
||||
const abort = () => {
|
||||
if (!event.node.res.writableEnded && stream && !stream.destroyed)
|
||||
stream.destroy(new Error("Client disconnected."));
|
||||
void close();
|
||||
};
|
||||
try {
|
||||
const chunk = await dropStore.readChunk(
|
||||
id,
|
||||
Number(getRouterParam(event, "index")),
|
||||
token,
|
||||
);
|
||||
handle = chunk.handle;
|
||||
stream = handle.createReadStream();
|
||||
event.node.res.once("close", abort);
|
||||
event.node.res.once("finish", close);
|
||||
setHeaders(event, {
|
||||
"content-type": "application/octet-stream",
|
||||
"content-length": chunk.size,
|
||||
"cache-control": "private, no-store",
|
||||
});
|
||||
return await sendStream(event, stream);
|
||||
} catch (error) {
|
||||
await close();
|
||||
if (error instanceof DropStoreError)
|
||||
throw createError({
|
||||
statusCode:
|
||||
error.code === "expired"
|
||||
? 410
|
||||
: error.code === "not-found"
|
||||
? 404
|
||||
: 403,
|
||||
statusMessage: error.message,
|
||||
});
|
||||
throw error;
|
||||
} finally {
|
||||
event.node.res.off("close", abort);
|
||||
event.node.res.off("finish", close);
|
||||
await close();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user