UNPKG

h3-compression

Version:

Adds compression to h3 request (brotli, gzip, deflate)

67 lines (62 loc) 2.35 kB
import { promisify } from 'node:util'; import zlib from 'node:zlib'; import { Buffer } from 'node:buffer'; import { getRequestHeader, setResponseHeader, send } from 'h3'; function getAnyCompression(event) { const encoding = getRequestHeader(event, "accept-encoding"); if (encoding?.includes("br")) return "br"; if (encoding?.includes("gzip")) return "gzip"; if (encoding?.includes("deflate")) return "deflate"; return void 0; } async function compress(event, response, method) { const compression = promisify(zlib[method === "br" ? "brotliCompress" : method]); const acceptsEncoding = getRequestHeader(event, "accept-encoding")?.includes( method ); if (acceptsEncoding && typeof response.body === "string") { setResponseHeader(event, "Content-Encoding", method); send(event, await compression(Buffer.from(response.body))); } } async function compressStream(event, response, method) { const stream = new Response(response.body).body; const acceptsEncoding = getRequestHeader(event, "accept-encoding")?.includes( method ); if (acceptsEncoding) { setResponseHeader(event, "Content-Encoding", method); response.body = stream.pipeThrough(new CompressionStream(method)); } else { response.body = stream; } } async function useGZipCompression(event, response) { await compress(event, response, "gzip"); } async function useDeflateCompression(event, response) { await compress(event, response, "deflate"); } async function useBrotliCompression(event, response) { await compress(event, response, "br"); } async function useCompression(event, response) { const compression = getAnyCompression(event); if (compression) await compress(event, response, compression); } async function useGZipCompressionStream(event, response) { await compressStream(event, response, "gzip"); } async function useDeflateCompressionStream(event, response) { await compressStream(event, response, "deflate"); } async function useCompressionStream(event, response) { const compression = getAnyCompression(event); if (compression && compression !== "br") await compressStream(event, response, compression); } export { useBrotliCompression, useCompression, useCompressionStream, useDeflateCompression, useDeflateCompressionStream, useGZipCompression, useGZipCompressionStream };