From 3f542c196a9893af3ef0e79bc6319d198c7b9c8e Mon Sep 17 00:00:00 2001 From: savearray2 <46784573+savearray2@users.noreply.github.com> Date: Wed, 27 Jan 2021 19:22:04 +0900 Subject: [PATCH] Adds Support for Generating Weak ETags (#31) (#32) * Adds Support for Generating Weak ETags (#31) * Adds Support for Generating Weak ETags (#31) Refactors the buildHashFn function to use external variable for ETag prefix. Co-authored-by: savearray2 --- README.md | 2 ++ index.d.ts | 1 + index.js | 9 +++++---- test/generic.js | 11 +++++++++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e61adb9..063c909 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ app.listen(3000) * `algorithm`: all hashing algorithm that Node.js support, and `'fnv1a'`. Default: `'fnv1a'`. +* `weak`: generates weak ETags by default. Default: `false`. + ## Acknowledgements The fnv1a logic was forked from https://github.com/sindresorhus/fnv1a diff --git a/index.d.ts b/index.d.ts index b3d1305..6264af2 100644 --- a/index.d.ts +++ b/index.d.ts @@ -3,6 +3,7 @@ import { Server, IncomingMessage, ServerResponse } from 'http'; export interface FastifyEtagOptions { algorithm?: 'fnv1a' | string; + weak?: false | boolean; } declare const fastifyEtag: FastifyPlugin diff --git a/index.js b/index.js index 558b9bf..bf2070a 100644 --- a/index.js +++ b/index.js @@ -4,17 +4,18 @@ const fp = require('fastify-plugin') const { createHash } = require('crypto') const fnv1a = require('./fnv1a') -function buildHashFn (algorithm = 'fnv1a') { +function buildHashFn (algorithm = 'fnv1a', weak = false) { + const prefix = weak ? 'W/"' : '"' if (algorithm === 'fnv1a') { - return (payload) => '"' + fnv1a(payload).toString(36) + '"' + return (payload) => prefix + fnv1a(payload).toString(36) + '"' } - return (payload) => '"' + createHash(algorithm) + return (payload) => prefix + createHash(algorithm) .update(payload).digest().toString('base64') + '"' } module.exports = fp(async function etag (app, opts) { - const hash = buildHashFn(opts.algorithm) + const hash = buildHashFn(opts.algorithm, opts.weak) app.addHook('onSend', function (req, reply, payload, done) { let etag = reply.getHeader('etag') diff --git a/test/generic.js b/test/generic.js index 4025770..61d3f81 100644 --- a/test/generic.js +++ b/test/generic.js @@ -89,4 +89,15 @@ module.exports = function ({ test }, etagOpts, hashFn) { etag: '"foobar"' }) }) + + test('returns a weak etag for each request when weak is in opts', async (t) => { + const res = await build({ weak: true }).inject({ + url: '/' + }) + + t.same(JSON.parse(res.body), { hello: 'world' }) + t.match(res.headers, { + etag: 'W/' + hash + }) + }) }