Spaces:
Running
Running
| import { | |
| DEFAULT_RELAY_STREAM_CHUNK_BYTES, | |
| filterResponseHeaders | |
| } from '../server/relay-protocol.js'; | |
| import { MAX_BODY_BYTES } from './relay-mac-client-config.mjs'; | |
| import { encodeResponseBody } from './relay-mac-client-body.mjs'; | |
| export function createHttpResponseSender({ | |
| sendRelayMessage, | |
| waitForRelayBackpressure | |
| }) { | |
| async function sendBuffered(requestId, response) { | |
| const encoded = await encodeResponseBody(response, { maxBodyBytes: MAX_BODY_BYTES }); | |
| if (encoded.type === 'http.error') { | |
| sendRelayMessage({ ...encoded, requestId }); | |
| return; | |
| } | |
| sendRelayMessage({ | |
| type: 'http.response', | |
| requestId, | |
| status: response.status, | |
| headers: filterResponseHeaders(response.headers), | |
| ...encoded | |
| }); | |
| } | |
| async function sendStreaming(requestId, response) { | |
| sendRelayMessage({ | |
| type: 'http.response.start', | |
| requestId, | |
| status: response.status, | |
| headers: filterResponseHeaders(response.headers) | |
| }); | |
| let sequence = 0; | |
| let totalBytes = 0; | |
| if (response.body) { | |
| for await (const chunk of response.body) { | |
| const buffer = Buffer.from(chunk); | |
| for (let offset = 0; offset < buffer.length; offset += DEFAULT_RELAY_STREAM_CHUNK_BYTES) { | |
| const slice = buffer.subarray(offset, offset + DEFAULT_RELAY_STREAM_CHUNK_BYTES); | |
| sequence += 1; | |
| totalBytes += slice.length; | |
| sendRelayMessage({ | |
| type: 'http.response.chunk', | |
| requestId, | |
| sequence, | |
| encoding: 'base64', | |
| data: slice.toString('base64'), | |
| bytes: slice.length | |
| }); | |
| await waitForRelayBackpressure(); | |
| } | |
| } | |
| } | |
| sendRelayMessage({ | |
| type: 'http.response.end', | |
| requestId, | |
| chunks: sequence, | |
| totalBytes | |
| }); | |
| } | |
| return { | |
| sendBuffered, | |
| sendStreaming | |
| }; | |
| } | |