diff --git a/src/lib/server/s3.ts b/src/lib/server/s3.ts index 51547f54..f1a63112 100644 --- a/src/lib/server/s3.ts +++ b/src/lib/server/s3.ts @@ -34,19 +34,20 @@ const client = * If the range is not satisfiable, a {@link RangeNotSatisfiableError} is thrown. * * @param key - The key of the object to get. + * @param opts.signal - Aborts the underlying S3 request when the consumer goes away, releasing the socket back to the pool. * @param opts.range - An optional range to retrieve a portion of the object. * @returns The object from S3, or `null` if the object does not exist. */ export async function getPodcastObject( key: string, - opts: { range?: string | null } = {}, + opts: { signal: AbortSignal; range?: string | null }, ): Promise<{ stream: ReadableStream; headers: Record; } | null> { try { const cmd = new GetObjectCommand({ Bucket: BUCKET, Key: key, Range: opts.range ?? undefined }); - const res = await client.send(cmd); + const res = await client.send(cmd, { abortSignal: opts.signal }); if (!res.Body || !(res.Body instanceof Readable)) { return null; @@ -54,6 +55,7 @@ export async function getPodcastObject( const stream = Readable.toWeb(res.Body); if (!(stream instanceof ReadableStream)) { + res.Body.destroy(); return null; } diff --git a/src/routes/(main)/(protected)/podcasts/[...key]/+server.ts b/src/routes/(main)/(protected)/podcasts/[...key]/+server.ts index e3e7d643..9b0fe01e 100644 --- a/src/routes/(main)/(protected)/podcasts/[...key]/+server.ts +++ b/src/routes/(main)/(protected)/podcasts/[...key]/+server.ts @@ -20,7 +20,10 @@ export const GET: RequestHandler = async (event) => { let podcast: Awaited> | null = null; try { - podcast = await getPodcastObject(`podcasts/${event.params.key}`, { range }); + podcast = await getPodcastObject(`podcasts/${event.params.key}`, { + range, + signal: event.request.signal, + }); if (!podcast) { return text(INVALID_REQUEST_BODY, { status: 400 }); }