| 123456789101112131415161718192021222324252627282930 |
- import { Effect, Stream } from "effect"
- import { HttpClientResponse } from "effect/unstable/http"
- export const collectBoundedResponseBody = (
- response: HttpClientResponse.HttpClientResponse,
- maximumBytes: number,
- tooLarge: () => Error,
- ) =>
- Effect.gen(function* () {
- const contentLength = response.headers["content-length"]
- const parsedSize = contentLength ? Number.parseInt(contentLength, 10) : undefined
- const declaredSize =
- parsedSize !== undefined && Number.isSafeInteger(parsedSize) && parsedSize >= 0 ? parsedSize : undefined
- if (declaredSize !== undefined && declaredSize > maximumBytes) return yield* Effect.fail(tooLarge())
- let body = Buffer.allocUnsafe(Math.min(maximumBytes, declaredSize || 64 * 1024))
- let size = 0
- yield* Stream.runForEach(response.stream, (chunk) => {
- if (chunk.byteLength === 0) return Effect.void
- if (size + chunk.byteLength > maximumBytes) return Effect.fail(tooLarge())
- if (size + chunk.byteLength > body.byteLength) {
- const grown = Buffer.allocUnsafe(Math.min(maximumBytes, Math.max(size + chunk.byteLength, body.byteLength * 2)))
- body.copy(grown, 0, 0, size)
- body = grown
- }
- body.set(chunk, size)
- size += chunk.byteLength
- return Effect.void
- })
- return body.subarray(0, size)
- })
|