UNPKG

pagespeed-quest

Version:

A framework for efficient web front-end speed improvement

96 lines 8.24 kB
import Crypto from 'crypto'; import Path from 'path'; const DirectoryIndex = 'index.html'; const BasenameMaxLength = 196; const HashLength = 8; const IgnoreParams = process.env.IGNORE_PARAMS || 'ts'; const IgnoreParamsRegex = IgnoreParams.split(/\s*,\s*/).map((p) => new RegExp(`(?<=[?&]${p}=)[^&]*`, 'g')); /** * Remove IgnoreParams from URL * Default: ts (timestamp) assumed different for each request * @param url * @returns */ export function normalizeUrl(url) { const urlObj = typeof url === 'string' ? new URL(url) : url; // Remove dynamic params if (urlObj.search !== '') { urlObj.search = IgnoreParamsRegex.reduce((search, re) => { return search.replace(re, ''); }, urlObj.search); } return urlObj; } /** * Convert URL to content file path * For example: * https://example.com/foo/bar.html?hoge=123 -> example.com/foo/bar~hoge=123.html * - Add directory index (index.html) if URL ends with slash * - Shorten too long basename with short hash * - Ignore dynamic params for example: ts=123 * @param url * @returns */ export function requestContentFilePath(method, url) { const urlObj = normalizeUrl(url); const protocol = urlObj.protocol.replace(/:/g, ''); const host = urlObj.host.replace(/:/g, '~'); // Directory Index (index.html) let pathname = urlObj.pathname; if (pathname.endsWith('/')) { pathname += DirectoryIndex; } else { const ext = Path.extname(pathname); if (ext === '') { pathname = Path.join(pathname, DirectoryIndex); } } const dir = Path.dirname(pathname); const ext = Path.extname(pathname); const base = Path.basename(pathname, ext); let filename = base; // Search params if (urlObj.search !== '') { // Remove dynamic params const search = IgnoreParamsRegex.reduce((search, re) => { return search.replace(re, ''); }, urlObj.search); filename = [filename, search.slice(1)].join('~'); } // Shorten too long basename if (filename.length > BasenameMaxLength) { const trunk = filename.slice(0, BasenameMaxLength); const hash = Crypto.createHash('sha1'); hash.update(filename); const digest = hash.digest('hex').slice(0, HashLength); filename = [trunk, digest].join('_'); } // Extension filename += ext; // Content file relative path const relPath = Path.join(dir, filename); return Path.join(method, protocol, host, relPath); } export function parseContentTypeHeader(contentType) { const [mime, ...params] = contentType.split(/;/).map((s) => s.trim()); const charsetParam = params.find((p) => p.startsWith('charset=')); return { mime, charset: charsetParam ? charsetParam.slice('charset='.length) : undefined, }; } export function stringifyContentTypeHeader(mime, charset, original) { const params = original ? original.split(/;/).map((s) => s.trim()) : []; if (mime) params[0] = mime; if (charset) { const charsetParamIndex = params.findIndex((p) => p.startsWith('charset=')); if (charsetParamIndex >= 0) params.splice(charsetParamIndex, 1, `charset=${charset}`); else params.splice(1, 0, `charset=${charset}`); } return params.join('; '); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9odHRwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQTtBQUMzQixPQUFPLElBQUksTUFBTSxNQUFNLENBQUE7QUFFdkIsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFBO0FBQ25DLE1BQU0saUJBQWlCLEdBQUcsR0FBRyxDQUFBO0FBQzdCLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQTtBQUNwQixNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUE7QUFDdEQsTUFBTSxpQkFBaUIsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO0FBSTFHOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxHQUFpQjtJQUM1QyxNQUFNLE1BQU0sR0FBRyxPQUFPLEdBQUcsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUE7SUFFM0Qsd0JBQXdCO0lBQ3hCLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxFQUFFLEVBQUU7UUFDeEIsTUFBTSxDQUFDLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLENBQVMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDOUQsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUMvQixDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0tBQ2xCO0lBRUQsT0FBTyxNQUFNLENBQUE7QUFDZixDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FB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