diff --git a/packages/server/src/route/comic.ts b/packages/server/src/route/comic.ts index d40b0c4..e6dad92 100644 --- a/packages/server/src/route/comic.ts +++ b/packages/server/src/route/comic.ts @@ -81,9 +81,9 @@ export async function renderComicPage({ path, page, reqHeaders, set }: RenderOpt if (await setHeadersForEntry(entry, reqHeaders, set)) { return null; } - - const readStream = await createReadableStreamFromZip(zip.reader, entry); - + + const abort = new AbortController(); + const readStream = await createReadableStreamFromZip(zip.reader, entry, { signal: abort.signal }); // Ensure zip file is closed after stream ends const streamWithCleanup = new ReadableStream({ async start(controller) { @@ -94,6 +94,7 @@ export async function renderComicPage({ path, page, reqHeaders, set }: RenderOpt if (done) break; controller.enqueue(value); } + abort.signal.throwIfAborted() controller.close(); } catch (error) { controller.error(error); @@ -102,8 +103,8 @@ export async function renderComicPage({ path, page, reqHeaders, set }: RenderOpt await zip.reader.close(); } }, - cancel: async () => { - await zip.reader.close(); + cancel: (reason) => { + abort.abort(); } }); diff --git a/packages/server/src/util/zipwrap.ts b/packages/server/src/util/zipwrap.ts index dc7cf7c..8a7f9bc 100644 --- a/packages/server/src/util/zipwrap.ts +++ b/packages/server/src/util/zipwrap.ts @@ -98,11 +98,16 @@ export async function entriesByNaturalOrder(zip: ZipReader) { return ret; } -export async function createReadableStreamFromZip(_zip: ZipReader, entry: Entry): Promise { +export async function createReadableStreamFromZip(_zip: ZipReader, entry: Entry, option?: { signal?: AbortSignal }): Promise { if (entry.getData === undefined) { throw new Error("entry.getData is undefined"); } const stream = new TransformStream(); - entry.getData(stream.writable); + entry.getData(stream.writable, { + signal: option?.signal, + }).catch(e => { + // ignore error. + // error is handled by stream.readable + }); return stream.readable; }