codexmobile-relay / scripts /relay-mac-client-http-response.mjs
Codex
deploy: CodexMobile Relay
90f0300
Raw
History Blame Contribute Delete
1.9 kB
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
};
}