UNPKG

@chubbyts/chubbyts-http-uwebsockets-bridge

Version:
63 lines (62 loc) 2.54 kB
import { PassThrough } from 'stream'; const getUri = (req, uriOptions) => { const query = req.getQuery(); const pathAndQuery = req.getUrl() + (query ? `?${query}` : ''); if (uriOptions === 'forwarded') { const headers = Object.fromEntries(['x-forwarded-proto', 'x-forwarded-host', 'x-forwarded-port'].map((name) => [name, req.getHeader(name)])); const missingHeaders = Object.keys(headers).filter((name) => !headers[name]); if (missingHeaders.length) { throw new Error(`Missing "${missingHeaders.join('", "')}" header(s).`); } const { 'x-forwarded-proto': schema, 'x-forwarded-host': host, 'x-forwarded-port': port } = headers; return `${schema}://${host}:${port}${pathAndQuery}`; } const hostHeader = req.getHeader('host'); const schema = uriOptions.schema ?? 'http'; const host = uriOptions.host ?? (hostHeader || 'localhost'); return `${schema}://${host}${pathAndQuery}`; }; const normalizeHeader = (header) => { return header .split(',') .map((headerPart) => headerPart.trim()) .filter((headerPart) => headerPart); }; const getBody = (res) => { const stream = new PassThrough(); res.onData((chunk, isLast) => { stream.write(Buffer.from(chunk)); if (isLast) { stream.end(); } }); return stream; }; export const createUwebsocketsToServerRequestFactory = (uriFactory, serverRequestFactory, streamFromResourceFactory, uriOptions = {}) => { return (req, res) => { const headers = {}; req.forEach((name, value) => { const normalizedHeaders = normalizeHeader(value); if (normalizedHeaders.length) { // eslint-disable-next-line functional/immutable-data headers[name] = normalizedHeaders; } }); return { ...serverRequestFactory(req.getMethod().toUpperCase(), uriFactory(getUri(req, uriOptions))), protocolVersion: '1.1', body: streamFromResourceFactory(getBody(res)), headers, }; }; }; export const createResponseToUwebsocketsEmitter = () => { return (response, res) => { res.writeStatus(`${response.status} ${response.reasonPhrase}`); Object.entries(response.headers).forEach(([name, value]) => { res.writeHeader(name, value.join(', ')); }); response.body.on('data', (data) => res.write(data)); response.body.on('end', () => res.end()); }; };