UNPKG

@versatiles/google-cloud

Version:
122 lines (121 loc) 4.67 kB
import zlib from 'zlib'; /** * Record mapping encoding types to their respective tools. * Provides implementations for 'br', 'gzip', and 'raw' encodings. */ export const ENCODINGS = { 'br': (() => { function getOptions(fast, size) { const params = { [zlib.constants.BROTLI_PARAM_QUALITY]: fast ? 3 : 11 }; if (size != null) params[zlib.constants.BROTLI_PARAM_SIZE_HINT] = size; return { params }; } // Brotli encoding tools return { name: 'br', // Implementations for Brotli-specific methods compressStream: (fast, size) => zlib.createBrotliCompress(getOptions(fast, size)), decompressStream: () => zlib.createBrotliDecompress(), compressBuffer: async (buffer, fast) => new Promise(resolve => { zlib.brotliCompress(buffer, getOptions(fast, buffer.length), (e, b) => { resolve(b); }); }), decompressBuffer: async (buffer) => new Promise(resolve => { zlib.brotliDecompress(buffer, (e, b) => { resolve(b); }); }), setEncodingHeader: (headers) => { headers.set('content-encoding', 'br'); return; }, }; })(), 'gzip': (() => { function getOptions(fast) { return { level: fast ? 3 : 9 }; } // Gzip encoding tools return { name: 'gzip', // Implementations for Gzip-specific methods compressStream: (fast) => zlib.createGzip(getOptions(fast)), decompressStream: () => zlib.createGunzip(), compressBuffer: async (buffer, fast) => new Promise(resolve => { zlib.gzip(buffer, getOptions(fast), (e, b) => { resolve(b); }); }), decompressBuffer: async (buffer) => new Promise(resolve => { zlib.gunzip(buffer, (e, b) => { resolve(b); }); }), setEncodingHeader: (headers) => { headers.set('content-encoding', 'gzip'); return; }, }; })(), 'raw': { name: 'raw', setEncodingHeader: (headers) => { headers.remove('content-encoding'); return; }, }, }; /** * Parses the content encoding from the given HTTP headers and returns the corresponding encoding tools. * @param headers - The outgoing HTTP headers. * @returns The corresponding `EncodingTools` based on the content encoding header. * @throws Error if the content encoding is unknown. */ export function parseContentEncoding(contentEncoding) { // Logic to parse content encoding if (contentEncoding == null) return ENCODINGS.raw; if (typeof contentEncoding !== 'string') throw Error(`unknown content-encoding ${JSON.stringify(contentEncoding)}`); const contentEncodingString = contentEncoding.trim().toLowerCase(); switch (contentEncodingString) { case '': return ENCODINGS.raw; case 'br': return ENCODINGS.br; case 'gzip': return ENCODINGS.gzip; } throw Error(`unknown content-encoding ${JSON.stringify(contentEncoding)}`); } /** * Determines the best encoding supported by the client based on the `accept-encoding` HTTP header. * @param headers - The incoming HTTP headers. * @returns The best available `EncodingTools` based on client's preferences. */ export function findBestEncoding(headers) { // Logic to find the best encoding const encodingHeader = headers['accept-encoding']; if (typeof encodingHeader !== 'string') return ENCODINGS.raw; const encodingString = encodingHeader.toLowerCase(); if (encodingString.includes('br')) return ENCODINGS.br; if (encodingString.includes('gzip')) return ENCODINGS.gzip; return ENCODINGS.raw; } /** * Checks if the given encoding is acceptable based on the `accept-encoding` HTTP header. * @param headers - The incoming HTTP headers. * @param encoding - The `EncodingTools` to check. * @returns `true` if the encoding is acceptable, otherwise `false`. */ export function acceptEncoding(headers, encoding) { // Logic to check if the encoding is acceptable if (encoding.name === 'raw') return true; const encodingHeader = headers['accept-encoding']; if (encodingHeader == null) return encoding === ENCODINGS.raw; return JSON.stringify(encodingHeader).toLowerCase().includes(encoding.name); }