UNPKG

@riddance/host

Version:

338 lines 40.9 kB
import { hash } from 'node:crypto'; import { isIP } from 'node:net'; import { brotliCompress } from 'node:zlib'; import { measure } from '../context.js'; export async function executeRequest(log, context, handler, options, success) { const isShallow = context.env.SHALLOW_KEY && options.headers?.['x-shallow'] === context.env.SHALLOW_KEY; const includeBodyInLogs = !handler.config?.excludeBodyFromLogs; const logRequest = includeBodyInLogs ? { method: handler.method, ...options } : withoutRequestBody({ method: handler.method, ...options }); let enrichedLog = log.enrichReserved({ meta: context.meta, request: logRequest }); if (isShallow) { enrichedLog.trace('Shallow request'); return { headers: {}, status: 204, }; } enrichedLog.trace('Request BEGIN'); try { let parsedUrl; let pathSteps; const req = { rawUrl: options.uri, get url() { if (parsedUrl) { return parsedUrl; } const url = new URL(this.rawUrl); parsedUrl = { // eslint-disable-next-line unicorn/no-null __proto__: null, hash: url.hash, host: url.host, hostname: url.hostname, href: url.href, origin: url.origin, password: url.password, pathname: url.pathname, port: url.port, protocol: url.protocol, search: url.search, get searchParams() { return url.searchParams; }, toJSON: () => url.toJSON(), toString: () => url.toString(), username: url.username, pathStepAt: (index) => { const steps = (pathSteps ??= url.pathname.split('/')); const step = steps[index + 1]; if (!step) { throw Object.assign(new RangeError(`Path does not have a step at index ${index}.`), { rawUrl: this.rawUrl, pathName: url.pathname, steps: steps.slice(1), }); } return step; }, }; return parsedUrl; }, body: requestBody(options), headers: options.headers ?? {}, }; const result = await measure(log.enrichReserved({ meta: context.meta }), 'execution', () => handler.entry({ ...context, log: enrichedLog }, req)); const response = resultToResponse(result, includeBodyInLogs); if (context.signal.aborted) { response.headers = { 'x-timeout': '1', ...response.headers, }; } enrichedLog = enrichedLog.enrichReserved({ response: { status: response.status, headers: response.headers, body: response.logBody, }, }); if (response.status < 300) { enrichedLog.debug('Request END'); await success(); } else { enrichedLog.warn('Request END'); } return await compressed(req.headers, eTagged(req.headers, response)); } catch (e) { try { const response = errorToResponse(e); enrichedLog = enrichedLog.enrichReserved({ response }); enrichedLog.error('Request END', e); return response; } catch (convertError) { enrichedLog.error('Could not convert exception to error response.', convertError); return { headers: {}, status: 500, }; } } } function resultToResponse(result, withLogBody) { if (!result) { return { headers: {}, status: 204, }; } else if (typeof result === 'string') { const logBody = withLogBody ? result : undefined; return { headers: { 'content-type': 'text/plain', }, status: 200, body: result, logBody, }; } else { if (result.body === undefined) { return { headers: result.headers ?? {}, status: result.status ?? 200, }; } else if (typeof result.body === 'string') { const logBody = withLogBody ? result.body : undefined; return { headers: withContentType(result.headers, 'text/plain'), status: result.status ?? 200, body: result.body, logBody, }; } else if (Buffer.isBuffer(result.body)) { const logBody = withLogBody ? result.body.toString('base64') : undefined; return { headers: withContentType(result.headers, 'application/octet-stream'), status: result.status ?? 200, body: result.body, logBody, }; } else { const logBody = withLogBody ? result.body : undefined; return { headers: withContentType(result.headers, 'application/json'), status: result.status ?? 200, body: JSON.stringify(result.body), logBody, }; } } } function withoutRequestBody(options) { if ('json' in options) { const { json, ...bodyless } = options; return bodyless; } if ('body' in options) { const { body, ...bodyless } = options; return bodyless; } return options; } function requestBody(options) { if ('json' in options) { return options.json; } if ('body' in options) { return options.body; } return undefined; } function withContentType(headers, contentType) { if (!headers) { return { 'content-type': contentType, }; } headers['content-type'] ??= contentType; return headers; } function errorToResponse(e) { const { body, statusCode: status } = e; if (typeof body === 'string') { return { headers: { 'content-type': 'text/plain', }, status: status ?? 500, body, }; } else if (typeof body === 'object') { return { headers: { 'content-type': 'application/json', }, status: status ?? 500, body: JSON.stringify(body), }; } else { return { headers: {}, status: status ?? 500, }; } } export function clientFromHeaders(headers) { if (!headers) { return {}; } return { operationId: headers['x-request-id'] ?? headers['request-id'], clientId: headers['x-client-id'] ?? headers['x-installation-id'] ?? headers['client-id'] ?? headers['installation-id'], ...clientAddress(headers), userAgent: headers['x-forwarded-for-user-agent'] ?? headers['user-agent'], }; } function clientAddress(headers) { const xff = headers['x-forwarded-for']; if (!xff) { return undefined; } for (const a of xff.split(',')) { const valid = validClientAddress(a.trim()); if (valid) { return valid; } } return undefined; } function validClientAddress(s) { const version = isIP(s); if (version === 4) { return { clientIp: s }; } if (version === 6) { return normalizedIp6(s); } if (s.startsWith('[') && s.endsWith(']')) { return normalizedIp6(s.slice(1, -1)); } if (s.startsWith(':')) { const clientPort = Number(s.slice(1)); if (Number.isFinite(clientPort)) { return { clientPort }; } return undefined; } const url = `ip://${s}/`; if (URL.canParse(url)) { return addressFromUrl(new URL(url)); } return undefined; } function normalizedIp6(s) { const mapped = mappedAddress(s); if (mapped) { return { clientIp: mapped }; } const url = new URL(`ip://[${s}]/`); return { clientIp: url.hostname.slice(1, -1) }; } function addressFromUrl(url) { const clientIp = url.hostname.startsWith('[') && url.hostname.endsWith(']') ? url.hostname.slice(1, -1) : url.hostname; const clientPort = url.port ? Number(url.port) : undefined; if (isIP(clientIp)) { return { clientIp, clientPort, }; } return undefined; } function mappedAddress(s) { if (s.startsWith('::ffff:')) { const ip4 = s.slice(7); if (isIP(ip4) === 4) { return ip4; } } return undefined; } function eTagged(requestHeaders, response) { if (response.headers.etag || !response.body) { return response; } const etag = hash('sha1', response.body, 'base64').slice(0, -1); response.headers.etag = etag; if (requestHeaders['if-none-match'] === etag) { response.status = 304; delete response.body; } return response; } async function compressed(requestHeaders, response) { if (!response.body || response.body.length < 32_768 || response.headers['content-encoding']) { return response; } const encodings = requestHeaders['accept-encoding']?.split(',').map(e => e.trim()); if (!encodings?.includes('br')) { return response; } return { status: response.status, headers: { 'content-encoding': 'br', ...response.headers, }, body: await compress(response.body), }; } function compress(body) { return new Promise((resolve, reject) => { brotliCompress(body, {}, (error, result) => { if (error) { reject(error); return; } resolve(result); }); }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImh0dHAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUNsQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBQy9CLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDMUMsT0FBTyxFQUFXLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQTBCaEQsTUFBTSxDQUFDLEtBQUssVUFBVSxjQUFjLENBQ2hDLEdBQWUsRUFDZixPQUE2QixFQUM3QixPQUFvQixFQUNwQixPQUF1QixFQUN2QixPQUErQjtJQUUvQixNQUFNLFNBQVMsR0FDWCxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsV0FBVyxDQUFDLEtBQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUE7SUFDekYsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsbUJBQW1CLENBQUE7SUFDOUQsTUFBTSxVQUFVLEdBQUcsaUJBQWlCO1FBQ2hDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsT0FBTyxFQUFFO1FBQ3hDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUMsQ0FBQTtJQUNoRSxJQUFJLFdBQVcsR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUE7SUFDakYsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNaLFdBQVcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQTtRQUNwQyxPQUFPO1lBQ0gsT0FB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QTtJQUNuQixDQUFDO0lBQ0QsT0FBTztRQUNILE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTTtRQUN2QixPQUFPLEVBQUU7WUFDTCxrQkFBa0IsRUFBRSxJQUFJO1lBQ3hCLEdBQUcsUUFBUSxDQUFDLE9BQU87U0FDdEI7UUFDRCxJQUFJLEVBQUUsTUFBTSxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztLQUN0QyxDQUFBO0FBQ0wsQ0FBQztBQUVELFNBQVMsUUFBUSxDQUFDLElBQXFCO0lBQ25DLE9BQU8sSUFBSSxPQUFPLENBQVMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDM0MsY0FBYyxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDdkMsSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDUixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7Z0JBQ2IsT0FBTTtZQUNWLENBQUM7WUFDRCxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbkIsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBoYXNoIH0gZnJvbSAnbm9kZTpjcnlwdG8nXG5pbXBvcnQgeyBpc0lQIH0gZnJvbSAnbm9kZTpuZXQnXG5pbXBvcnQgeyBicm90bGlDb21wcmVzcyB9IGZyb20gJ25vZGU6emxpYidcbmltcG9ydCB7IENvbnRleHQsIG1lYXN1cmUgfSBmcm9tICcuLi9jb250ZXh0LmpzJ1xuaW1wb3J0IHR5cGUgeyBKc29uLCBQYXJzZWRVcmwsIFJlc3BvbnNlSGVhZGVycywgUmVzdWx0IH0gZnJvbSAnLi4vaHR0cC5qcydcbmltcG9ydCB7IENsaWVudEluZm8sIFJvb3RMb2dnZXIgfSBmcm9tICcuL2NvbnRleHQuanMnXG5pbXBvcnQgdHlwZSB7IEh0dHBIYW5kbGVyIH0gZnJvbSAnLi9odHRwLXJlZ2lzdHJ5LmpzJ1xuXG5leHBvcnQgdHlwZSBSZXNwb25zZSA9IHtcbiAgICBoZWFkZXJzOiB7IHJlYWRvbmx5IFtrZXk6IHN0cmluZ106IHN0cmluZyB9XG4gICAgc3RhdHVzOiBudW1iZXJcbiAgICBib2R5Pzogc3RyaW5nIHwgQnVmZmVyXG59XG5cbnR5cGUgUmVxdWVzdE9wdGlvbnMgPSBCb2R5bGVzc1JlcXVlc3RPcHRpb25zIHwgU3RyaW5nUmVxdWVzdE9wdGlvbnMgfCBKc29uUmVxdWVzdE9wdGlvbnNcblxudHlwZSBCb2R5bGVzc1JlcXVlc3RPcHRpb25zID0ge1xuICAgIHVyaTogc3RyaW5nXG4gICAgaGVhZGVycz86IHsgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogc3RyaW5nIH1cbn1cblxudHlwZSBTdHJpbmdSZXF1ZXN0T3B0aW9ucyA9IEJvZHlsZXNzUmVxdWVzdE9wdGlvbnMgJiB7XG4gICAgYm9keTogc3RyaW5nXG59XG5cbnR5cGUgSnNvblJlcXVlc3RPcHRpb25zID0gQm9keWxlc3NSZXF1ZXN0T3B0aW9ucyAmIHtcbiAgICBqc29uOiBKc29uXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleGVjdXRlUmVxdWVzdChcbiAgICBsb2c6IFJvb3RMb2dnZXIsXG4gICAgY29udGV4dDogT21pdDxDb250ZXh0LCAnbG9nJz4sXG4gICAgaGFuZGxlcjogSHR0cEhhbmRsZXIsXG4gICAgb3B0aW9uczogUmVxdWVzdE9wdGlvbnMsXG4gICAgc3VjY2VzczogKCkgPT4gUHJvbWlzZTx1bmtub3duPixcbik6IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgICBjb25zdCBpc1NoYWxsb3cgPVxuICAgICAgICBjb250ZXh0LmVudi5TSEFMTE9XX0tFWSAmJiBvcHRpb25zLmhlYWRlcnM/LlsneC1zaGFsbG93J10gPT09IGNvbnRleHQuZW52LlNIQUxMT1dfS0VZXG4gICAgY29uc3QgaW5jbHVkZUJvZHlJbkxvZ3MgPSAhaGFuZGxlci5jb25maWc/LmV4Y2x1ZGVCb2R5RnJvbUxvZ3NcbiAgICBjb25zdCBsb2dSZXF1ZXN0ID0gaW5jbHVkZUJvZHlJbkxvZ3NcbiAgICAgICAgPyB7IG1ldGhvZDogaGFuZGxlci5tZXRob2QsIC4uLm9wdGlvbnMgfVxuICAgICAgICA6IHdpdGhvdXRSZXF1ZXN0Qm9keSh7IG1ldGhvZDogaGFuZGxlci5tZXRob2QsIC4uLm9wdGlvbnMgfSlcbiAgICBsZXQgZW5yaWNoZWRMb2cgPSBsb2cuZW5yaWNoUmVzZXJ2ZWQoeyBtZXRhOiBjb250ZXh0Lm1ldGEsIHJlcXVlc3Q6IGxvZ1JlcXVlc3QgfSlcbiAgICBpZiAoaXNTaGFsbG93KSB7XG4gICAgICAgIGVucmljaGVkTG9nLnRyYWNlKCdTaGFsbG93IHJlcXVlc3QnKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgICAgICBzdGF0dXM6IDIwNCxcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbnJpY2hlZExvZy50cmFjZSgnUmVxdWVzdCBCRUdJTicpXG4gICAgdHJ5IHtcbiAgICAgICAgbGV0IHBhcnNlZFVybDpcbiAgICAgICAgICAgIHwgKFBhcnNlZFVybCAmIHtcbiAgICAgICAgICAgICAgICAgIC8qKiBAaWdub3JlICovXG4gICAgICAgICAgICAgICAgICBfX3Byb3RvX186IHVua25vd25cbiAgICAgICAgICAgICAgICAgIC8qKiBAaWdub3JlICovXG4gICAgICAgICAgICAgICAgICB0b1N0cmluZzogKCkgPT4gc3RyaW5nXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB8IHVuZGVmaW5lZFxuICAgICAgICBsZXQgcGF0aFN0ZXBzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZFxuICAgICAgICBjb25zdCByZXEgPSB7XG4gICAgICAgICAgICByYXdVcmw6IG9wdGlvbnMudXJpLFxuICAgICAgICAgICAgZ2V0IHVybCgpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFyc2VkVXJsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZWRVcmxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgdXJsID0gbmV3IFVSTCh0aGlzLnJhd1VybClcbiAgICAgICAgICAgICAgICBwYXJzZWRVcmwgPSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL25vLW51bGxcbiAgICAgICAgICAgICAgICAgICAgX19wcm90b19fOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBoYXNoOiB1cmwuaGFzaCxcbiAgICAgICAgICAgICAgICAgICAgaG9zdDogdXJsLmhvc3QsXG4gICAgICAgICAgICAgICAgICAgIGhvc3RuYW1lOiB1cmwuaG9zdG5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGhyZWY6IHVybC5ocmVmLFxuICAgICAgICAgICAgICAgICAgICBvcmlnaW46IHVybC5vcmlnaW4sXG4gICAgICAgICAgICAgICAgICAgIHBhc3N3b3JkOiB1cmwucGFzc3dvcmQsXG4gICAgICAgICAgICAgICAgICAgIHBhdGhuYW1lOiB1cmwucGF0aG5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHBvcnQ6IHVybC5wb3J0LFxuICAgICAgICAgICAgICAgICAgICBwcm90b2NvbDogdXJsLnByb3RvY29sLFxuICAgICAgICAgICAgICAgICAgICBzZWFyY2g6IHVybC5zZWFyY2gsXG4gICAgICAgICAgICAgICAgICAgIGdldCBzZWFyY2hQYXJhbXMoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXJsLnNlYXJjaFBhcmFtc1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB0b0pTT046ICgpID0+IHVybC50b0pTT04oKSxcbiAgICAgICAgICAgICAgICAgICAgdG9TdHJpbmc6ICgpID0+IHVybC50b1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICB1c2VybmFtZTogdXJsLnVzZXJuYW1lLFxuICAgICAgICAgICAgICAgICAgICBwYXRoU3RlcEF0OiAoaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RlcHMgPSAocGF0aFN0ZXBzID8/PSB1cmwucGF0aG5hbWUuc3BsaXQoJy8nKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0ZXAgPSBzdGVwc1tpbmRleCArIDFdXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0ZXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBPYmplY3QuYXNzaWduKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUmFuZ2VFcnJvcihgUGF0aCBkb2VzIG5vdCBoYXZlIGEgc3RlcCBhdCBpbmRleCAke2luZGV4fS5gKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3VXJsOiB0aGlzLnJhd1VybCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGhOYW1lOiB1cmwucGF0aG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwczogc3RlcHMuc2xpY2UoMSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0ZXBcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlZFVybFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJvZHk6IHJlcXVlc3RCb2R5KG9wdGlvbnMpLFxuICAgICAgICAgICAgaGVhZGVyczogb3B0aW9ucy5oZWFkZXJzID8/IHt9LFxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbWVhc3VyZShsb2cuZW5yaWNoUmVzZXJ2ZWQoeyBtZXRhOiBjb250ZXh0Lm1ldGEgfSksICdleGVjdXRpb24nLCAoKSA9PlxuICAgICAgICAgICAgaGFuZGxlci5lbnRyeSh7IC4uLmNvbnRleHQsIGxvZzogZW5yaWNoZWRMb2cgfSwgcmVxKSxcbiAgICAgICAgKVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gcmVzdWx0VG9SZXNwb25zZShyZXN1bHQsIGluY2x1ZGVCb2R5SW5Mb2dzKVxuXG4gICAgICAgIGlmIChjb250ZXh0LnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgICAgICAgICByZXNwb25zZS5oZWFkZXJzID0ge1xuICAgICAgICAgICAgICAgICd4LXRpbWVvdXQnOiAnMScsXG4gICAgICAgICAgICAgICAgLi4ucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGVucmljaGVkTG9nID0gZW5yaWNoZWRMb2cuZW5yaWNoUmVzZXJ2ZWQoe1xuICAgICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgICAgICAgIGJvZHk6IHJlc3BvbnNlLmxvZ0JvZHksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzIDwgMzAwKSB7XG4gICAgICAgICAgICBlbnJpY2hlZExvZy5kZWJ1ZygnUmVxdWVzdCBFTkQnKVxuICAgICAgICAgICAgYXdhaXQgc3VjY2VzcygpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbnJpY2hlZExvZy53YXJuKCdSZXF1ZXN0IEVORCcpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF3YWl0IGNvbXByZXNzZWQocmVxLmhlYWRlcnMsIGVUYWdnZWQocmVxLmhlYWRlcnMsIHJlc3BvbnNlKSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGVycm9yVG9SZXNwb25zZShlKVxuICAgICAgICAgICAgZW5yaWNoZWRMb2cgPSBlbnJpY2hlZExvZy5lbnJpY2hSZXNlcnZlZCh7IHJlc3BvbnNlIH0pXG4gICAgICAgICAgICBlbnJpY2hlZExvZy5lcnJvcignUmVxdWVzdCBFTkQnLCBlKVxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlXG4gICAgICAgIH0gY2F0Y2ggKGNvbnZlcnRFcnJvcikge1xuICAgICAgICAgICAgZW5yaWNoZWRMb2cuZXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGV4Y2VwdGlvbiB0byBlcnJvciByZXNwb25zZS4nLCBjb252ZXJ0RXJyb3IpXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICAgICAgICAgIHN0YXR1czogNTAwLFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZXN1bHRUb1Jlc3BvbnNlKHJlc3VsdDogUmVzdWx0LCB3aXRoTG9nQm9keTogYm9vbGVhbik6IFJlc3BvbnNlICYgeyBsb2dCb2R5PzogdW5rbm93biB9IHtcbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgICAgICBzdGF0dXM6IDIwNCxcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgbG9nQm9keSA9IHdpdGhMb2dCb2R5ID8gcmVzdWx0IDogdW5kZWZpbmVkXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICd0ZXh0L3BsYWluJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICAgIGJvZHk6IHJlc3VsdCxcbiAgICAgICAgICAgIGxvZ0JvZHksXG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAocmVzdWx0LmJvZHkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiByZXN1bHQuaGVhZGVycyA/PyB7fSxcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHJlc3VsdC5zdGF0dXMgPz8gMjAwLFxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiByZXN1bHQuYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGNvbnN0IGxvZ0JvZHkgPSB3aXRoTG9nQm9keSA/IHJlc3VsdC5ib2R5IDogdW5kZWZpbmVkXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHdpdGhDb250ZW50VHlwZShyZXN1bHQuaGVhZGVycywgJ3RleHQvcGxhaW4nKSxcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHJlc3VsdC5zdGF0dXMgPz8gMjAwLFxuICAgICAgICAgICAgICAgIGJvZHk6IHJlc3VsdC5ib2R5LFxuICAgICAgICAgICAgICAgIGxvZ0JvZHksXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKHJlc3VsdC5ib2R5KSkge1xuICAgICAgICAgICAgY29uc3QgbG9nQm9keSA9IHdpdGhMb2dCb2R5ID8gcmVzdWx0LmJvZHkudG9TdHJpbmcoJ2Jhc2U2NCcpIDogdW5kZWZpbmVkXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHdpdGhDb250ZW50VHlwZShyZXN1bHQuaGVhZGVycywgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpLFxuICAgICAgICAgICAgICAgIHN0YXR1czogcmVzdWx0LnN0YXR1cyA/PyAyMDAsXG4gICAgICAgICAgICAgICAgYm9keTogcmVzdWx0LmJvZHksXG4gICAgICAgICAgICAgICAgbG9nQm9keSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGxvZ0JvZHkgPSB3aXRoTG9nQm9keSA/IHJlc3VsdC5ib2R5IDogdW5kZWZpbmVkXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHdpdGhDb250ZW50VHlwZShyZXN1bHQuaGVhZGVycywgJ2FwcGxpY2F0aW9uL2pzb24nKSxcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHJlc3VsdC5zdGF0dXMgPz8gMjAwLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHJlc3VsdC5ib2R5KSxcbiAgICAgICAgICAgICAgICBsb2dCb2R5LFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiB3aXRob3V0UmVxdWVzdEJvZHkob3B0aW9uczogUmVxdWVzdE9wdGlvbnMgJiB7IG1ldGhvZDogc3RyaW5nIH0pIHtcbiAgICBpZiAoJ2pzb24nIGluIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgeyBqc29uLCAuLi5ib2R5bGVzcyB9ID0gb3B0aW9uc1xuICAgICAgICByZXR1cm4gYm9keWxlc3NcbiAgICB9XG4gICAgaWYgKCdib2R5JyBpbiBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHsgYm9keSwgLi4uYm9keWxlc3MgfSA9IG9wdGlvbnNcbiAgICAgICAgcmV0dXJuIGJvZHlsZXNzXG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zXG59XG5cbmZ1bmN0aW9uIHJlcXVlc3RCb2R5KG9wdGlvbnM6IFJlcXVlc3RPcHRpb25zKTogSnNvbiB8IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCdqc29uJyBpbiBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zLmpzb25cbiAgICB9XG4gICAgaWYgKCdib2R5JyBpbiBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zLmJvZHlcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiB3aXRoQ29udGVudFR5cGUoaGVhZGVyczogUmVzcG9uc2VIZWFkZXJzIHwgdW5kZWZpbmVkLCBjb250ZW50VHlwZTogc3RyaW5nKSB7XG4gICAgaWYgKCFoZWFkZXJzKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogY29udGVudFR5cGUsXG4gICAgICAgIH1cbiAgICB9XG4gICAgaGVhZGVyc1snY29udGVudC10eXBlJ10gPz89IGNvbnRlbnRUeXBlXG4gICAgcmV0dXJuIGhlYWRlcnNcbn1cblxuZnVuY3Rpb24gZXJyb3JUb1Jlc3BvbnNlKGU6IHVua25vd24pOiBSZXNwb25zZSB7XG4gICAgY29uc3QgeyBib2R5LCBzdGF0dXNDb2RlOiBzdGF0dXMgfSA9IGUgYXMgeyBib2R5PzogdW5rbm93bjsgc3RhdHVzQ29kZT86IG51bWJlciB9XG4gICAgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAndGV4dC9wbGFpbicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMgPz8gNTAwLFxuICAgICAgICAgICAgYm9keSxcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGJvZHkgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cyA/PyA1MDAsXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShib2R5KSxcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoZWFkZXJzOiB7fSxcbiAgICAgICAgICAgIHN0YXR1czogc3RhdHVzID8/IDUwMCxcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsaWVudEZyb21IZWFkZXJzKFxuICAgIGhlYWRlcnM6IHsgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkIH0gfCB1bmRlZmluZWQsXG4pOiBDbGllbnRJbmZvIHtcbiAgICBpZiAoIWhlYWRlcnMpIHtcbiAgICAgICAgcmV0dXJuIHt9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIG9wZXJhdGlvbklkOiBoZWFkZXJzWyd4LXJlcXVlc3QtaWQnXSA/PyBoZWFkZXJzWydyZXF1ZXN0LWlkJ10sXG4gICAgICAgIGNsaWVudElkOlxuICAgICAgICAgICAgaGVhZGVyc1sneC1jbGllbnQtaWQnXSA/P1xuICAgICAgICAgICAgaGVhZGVyc1sneC1pbnN0YWxsYXRpb24taWQnXSA/P1xuICAgICAgICAgICAgaGVhZGVyc1snY2xpZW50LWlkJ10gPz9cbiAgICAgICAgICAgIGhlYWRlcnNbJ2luc3RhbGxhdGlvbi1pZCddLFxuICAgICAgICAuLi5jbGllbnRBZGRyZXNzKGhlYWRlcnMpLFxuICAgICAgICB1c2VyQWdlbnQ6IGhlYWRlcnNbJ3gtZm9yd2FyZGVkLWZvci11c2VyLWFnZW50J10gPz8gaGVhZGVyc1sndXNlci1hZ2VudCddLFxuICAgIH1cbn1cblxuZnVuY3Rpb24gY2xpZW50QWRkcmVzcyhoZWFkZXJzOiB7IHJlYWRvbmx5IFtrZXk6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZCB9KSB7XG4gICAgY29uc3QgeGZmID0gaGVhZGVyc1sneC1mb3J3YXJkZWQtZm9yJ11cbiAgICBpZiAoIXhmZikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuICAgIGZvciAoY29uc3QgYSBvZiB4ZmYuc3BsaXQoJywnKSkge1xuICAgICAgICBjb25zdCB2YWxpZCA9IHZhbGlkQ2xpZW50QWRkcmVzcyhhLnRyaW0oKSlcbiAgICAgICAgaWYgKHZhbGlkKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsaWRcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIHZhbGlkQ2xpZW50QWRkcmVzcyhzOiBzdHJpbmcpIHtcbiAgICBjb25zdCB2ZXJzaW9uID0gaXNJUChzKVxuICAgIGlmICh2ZXJzaW9uID09PSA0KSB7XG4gICAgICAgIHJldHVybiB7IGNsaWVudElwOiBzIH1cbiAgICB9XG4gICAgaWYgKHZlcnNpb24gPT09IDYpIHtcbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRJcDYocylcbiAgICB9XG4gICAgaWYgKHMuc3RhcnRzV2l0aCgnWycpICYmIHMuZW5kc1dpdGgoJ10nKSkge1xuICAgICAgICByZXR1cm4gbm9ybWFsaXplZElwNihzLnNsaWNlKDEsIC0xKSlcbiAgICB9XG4gICAgaWYgKHMuc3RhcnRzV2l0aCgnOicpKSB7XG4gICAgICAgIGNvbnN0IGNsaWVudFBvcnQgPSBOdW1iZXIocy5zbGljZSgxKSlcbiAgICAgICAgaWYgKE51bWJlci5pc0Zpbml0ZShjbGllbnRQb3J0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgY2xpZW50UG9ydCB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH1cbiAgICBjb25zdCB1cmwgPSBgaXA6Ly8ke3N9L2BcbiAgICBpZiAoVVJMLmNhblBhcnNlKHVybCkpIHtcbiAgICAgICAgcmV0dXJuIGFkZHJlc3NGcm9tVXJsKG5ldyBVUkwodXJsKSlcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBub3JtYWxpemVkSXA2KHM6IHN0cmluZykge1xuICAgIGNvbnN0IG1hcHBlZCA9IG1hcHBlZEFkZHJlc3MocylcbiAgICBpZiAobWFwcGVkKSB7XG4gICAgICAgIHJldHVybiB7IGNsaWVudElwOiBtYXBwZWQgfVxuICAgIH1cbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKGBpcDovL1ske3N9XS9gKVxuICAgIHJldHVybiB7IGNsaWVudElwOiB1cmwuaG9zdG5hbWUuc2xpY2UoMSwgLTEpIH1cbn1cblxuZnVuY3Rpb24gYWRkcmVzc0Zyb21VcmwodXJsOiBVUkwpIHtcbiAgICBjb25zdCBjbGllbnRJcCA9XG4gICAgICAgIHVybC5ob3N0bmFtZS5zdGFydHNXaXRoKCdbJykgJiYgdXJsLmhvc3RuYW1lLmVuZHNXaXRoKCddJylcbiAgICAgICAgICAgID8gdXJsLmhvc3RuYW1lLnNsaWNlKDEsIC0xKVxuICAgICAgICAgICAgOiB1cmwuaG9zdG5hbWVcbiAgICBjb25zdCBjbGllbnRQb3J0ID0gdXJsLnBvcnQgPyBOdW1iZXIodXJsLnBvcnQpIDogdW5kZWZpbmVkXG4gICAgaWYgKGlzSVAoY2xpZW50SXApKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjbGllbnRJcCxcbiAgICAgICAgICAgIGNsaWVudFBvcnQsXG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBtYXBwZWRBZGRyZXNzKHM6IHN0cmluZykge1xuICAgIGlmIChzLnN0YXJ0c1dpdGgoJzo6ZmZmZjonKSkge1xuICAgICAgICBjb25zdCBpcDQgPSBzLnNsaWNlKDcpXG4gICAgICAgIGlmIChpc0lQKGlwNCkgPT09IDQpIHtcbiAgICAgICAgICAgIHJldHVybiBpcDRcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGVUYWdnZWQoXG4gICAgcmVxdWVzdEhlYWRlcnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICAgcmVzcG9uc2U6IFJlc3BvbnNlICYgeyBoZWFkZXJzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IH0sXG4pOiBSZXNwb25zZSB7XG4gICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZXRhZyB8fCAhcmVzcG9uc2UuYm9keSkge1xuICAgICAgICByZXR1cm4gcmVzcG9uc2VcbiAgICB9XG4gICAgY29uc3QgZXRhZyA9IGhhc2goJ3NoYTEnLCByZXNwb25zZS5ib2R5LCAnYmFzZTY0Jykuc2xpY2UoMCwgLTEpXG4gICAgcmVzcG9uc2UuaGVhZGVycy5ldGFnID0gZXRhZ1xuICAgIGlmIChyZXF1ZXN0SGVhZGVyc1snaWYtbm9uZS1tYXRjaCddID09PSBldGFnKSB7XG4gICAgICAgIHJlc3BvbnNlLnN0YXR1cyA9IDMwNFxuICAgICAgICBkZWxldGUgcmVzcG9uc2UuYm9keVxuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2Vcbn1cblxuYXN5bmMgZnVuY3Rpb24gY29tcHJlc3NlZChcbiAgICByZXF1ZXN0SGVhZGVyczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSxcbiAgICByZXNwb25zZTogUmVzcG9uc2UgJiB7IGhlYWRlcnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gfSxcbik6IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgICBpZiAoIXJlc3BvbnNlLmJvZHkgfHwgcmVzcG9uc2UuYm9keS5sZW5ndGggPCAzMl83NjggfHwgcmVzcG9uc2UuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddKSB7XG4gICAgICAgIHJldHVybiByZXNwb25zZVxuICAgIH1cbiAgICBjb25zdCBlbmNvZGluZ3MgPSByZXF1ZXN0SGVhZGVyc1snYWNjZXB0LWVuY29kaW5nJ10/LnNwbGl0KCcsJykubWFwKGUgPT4gZS50cmltKCkpXG4gICAgaWYgKCFlbmNvZGluZ3M/LmluY2x1ZGVzKCdicicpKSB7XG4gICAgICAgIHJldHVybiByZXNwb25zZVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ2NvbnRlbnQtZW5jb2RpbmcnOiAnYnInLFxuICAgICAgICAgICAgLi4ucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgfSxcbiAgICAgICAgYm9keTogYXdhaXQgY29tcHJlc3MocmVzcG9uc2UuYm9keSksXG4gICAgfVxufVxuXG5mdW5jdGlvbiBjb21wcmVzcyhib2R5OiBzdHJpbmcgfCBCdWZmZXIpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8QnVmZmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGJyb3RsaUNvbXByZXNzKGJvZHksIHt9LCAoZXJyb3IsIHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpXG4gICAgICAgIH0pXG4gICAgfSlcbn1cbiJdfQ==