diff --git a/src/app/minio-images/[...key]/route.ts b/src/app/minio-images/[...key]/route.ts index 3b8d2b7..fe39a50 100644 --- a/src/app/minio-images/[...key]/route.ts +++ b/src/app/minio-images/[...key]/route.ts @@ -37,12 +37,20 @@ export async function GET( const object = await getImage(key) if (!object.Body) return new Response(null, { status: 404 }) - return new Response(object.Body as unknown as ReadableStream, { + // The SDK hands back a Node IncomingMessage, not a web ReadableStream. undici + // happens to accept it, but transformToByteArray is the documented API and keeps + // the types honest. Buffering is fine here - uploads are capped at 10MB. + const bytes = await object.Body.transformToByteArray() + // Copy out to a plain ArrayBuffer: a Uint8Array view is not a valid BodyInit. + const body = bytes.buffer.slice( + bytes.byteOffset, + bytes.byteOffset + bytes.byteLength + ) as ArrayBuffer + + return new Response(body, { headers: { "Content-Type": object.ContentType ?? "application/octet-stream", - ...(object.ContentLength - ? { "Content-Length": String(object.ContentLength) } - : {}), + "Content-Length": String(bytes.byteLength), // Keys embed a random UUID, so an object never changes under a given key. // `private` keeps it out of any shared cache now that it is session-gated. "Cache-Control": "private, max-age=31536000, immutable",