From c1ce6c215743853ade5f0d65e2b2b55addc0ce2c Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Thu, 10 Nov 2022 14:15:59 +0300 Subject: [PATCH] perf: avoid redundant buffers init --- src/main/js/firewall/middleware.js | 11 +++++++---- src/main/js/firewall/packument.js | 12 +++++------- src/main/js/util.js | 2 ++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/main/js/firewall/middleware.js b/src/main/js/firewall/middleware.js index af60bc2..9141301 100644 --- a/src/main/js/firewall/middleware.js +++ b/src/main/js/firewall/middleware.js @@ -1,7 +1,8 @@ +import {Buffer} from 'node:buffer' import {httpError, NOT_FOUND, ACCESS_DENIED, METHOD_NOT_ALLOWED, NOT_MODIFIED, OK, FOUND} from '../http/index.js' import {getPolicy, getPipeline} from './engine.js' import {getPackument} from './packument.js' -import {normalizePath, gunzip, dropNullEntries, time} from '../util.js' +import {normalizePath, gzip, dropNullEntries, time, jsonBuffer} from '../util.js' import {hasHit, hasKey, isNoCache} from '../cache.js' import {getCtx} from '../als.js' import {checkTarball} from './tarball.js' @@ -60,14 +61,14 @@ export const firewall = ({registry, rules, entrypoint: _entrypoint, token}) => a warmupPipeline(pipeline, boundContext) const [ - { packumentBuffer, headers, etag, deps, directives }, + { packument, packumentBufferZip, headers, etag, deps, directives }, tarball ] = await Promise.all([ getPackument({ boundContext, rules }), version ? checkTarball({registry, url: req.url}) : Promise.resolve(false) ]) - if (!packumentBuffer) { + if (!packument) { return next(httpError(NOT_FOUND)) } @@ -95,7 +96,9 @@ export const firewall = ({registry, rules, entrypoint: _entrypoint, token}) => a // Packument request const isGzip = req.headers['accept-encoding']?.includes('gzip') - const buffer = isGzip ? packumentBuffer : await time(gunzip, `gunzip packument ${name}`)(packumentBuffer) + const buffer = isGzip + ? packumentBufferZip || await time(gzip, `gzip packument ${name}`)(jsonBuffer(packument)) + : jsonBuffer(packument) const cl = '' + buffer.length const extra = isGzip ? {'content-length': cl, 'transfer-encoding': null, 'content-encoding': 'gzip', etag} diff --git a/src/main/js/firewall/packument.js b/src/main/js/firewall/packument.js index 2e4cfb3..fb1b5e3 100644 --- a/src/main/js/firewall/packument.js +++ b/src/main/js/firewall/packument.js @@ -1,4 +1,3 @@ -import {Buffer} from 'node:buffer' import crypto from 'node:crypto' import {getDirectives, getPolicy} from './engine.js' @@ -25,14 +24,13 @@ export const getPackument = async ({boundContext, rules}) => { const deps = getDeps(packument) const directives = await getDirectives({ packument, rules, boundContext}) const _packument = patchPackument({ packument, directives, entrypoint, registry }) + const vkeys = Object.keys(_packument.versions) - if (Object.keys(_packument.versions).length === 0) { + if (vkeys.length === 0) { return {} } - const packumentBuffer = Object.keys(_packument.versions).length === Object.keys(packument.versions).length - ? buffer - : Buffer.from(JSON.stringify(_packument)) - const etag = 'W/' + JSON.stringify(crypto.createHash('sha256').update(packumentBuffer.slice(0, 65_536)).digest('hex')) + const packumentBufferZip = vkeys.length === Object.keys(packument.versions).length && buffer + const etag = 'W/' + JSON.stringify(crypto.createHash('sha256').update(`${packument.name}${vkeys.join(',')}`).digest('hex')) return { etag, @@ -40,7 +38,7 @@ export const getPackument = async ({boundContext, rules}) => { directives, headers, packument: _packument, - packumentBuffer, + packumentBufferZip, } } diff --git a/src/main/js/util.js b/src/main/js/util.js index c209e53..1c3f346 100644 --- a/src/main/js/util.js +++ b/src/main/js/util.js @@ -198,3 +198,5 @@ export const time = (fn, label = fn.name) => async (...args) => { } export const setFnName = (fn, name) => Object.defineProperty(fn, 'name', { value: name }) + +export const jsonBuffer = (v) => Buffer.from(JSON.stringify(v))