From 3ee0a1e760bc88321e55748291b1a3b62f4e7f13 Mon Sep 17 00:00:00 2001 From: uzlopak Date: Fri, 3 Feb 2023 22:28:30 +0100 Subject: [PATCH] improve containsDotFile --- benchmarks/containsDotFile.js | 15 +++++++++++++++ lib/SendStream.js | 31 +++++++++++++++++++++++-------- lib/containsDotFile.js | 8 ++++---- test/containsDotFile.test.js | 18 ++++++++++++++++++ 4 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 benchmarks/containsDotFile.js create mode 100644 test/containsDotFile.test.js diff --git a/benchmarks/containsDotFile.js b/benchmarks/containsDotFile.js new file mode 100644 index 0000000..a9cbfc4 --- /dev/null +++ b/benchmarks/containsDotFile.js @@ -0,0 +1,15 @@ +'use strict' + +const benchmark = require('benchmark') +const { containsDotFile } = require('../lib/containsDotFile') + +const hasDotFileSimple = '.github'.split('/') +const hasDotFile = './.github'.split('/') +const noDotFile = './index.html'.split('/') + +new benchmark.Suite() + .add(hasDotFileSimple.join('/'), function () { containsDotFile(hasDotFileSimple) }, { minSamples: 100 }) + .add(noDotFile.join('/'), function () { containsDotFile(noDotFile) }, { minSamples: 100 }) + .add(hasDotFile.join('/'), function () { containsDotFile(hasDotFile) }, { minSamples: 100 }) + .on('cycle', function onCycle (event) { console.log(String(event.target)) }) + .run({ async: false }) diff --git a/lib/SendStream.js b/lib/SendStream.js index b1c9320..b490f42 100644 --- a/lib/SendStream.js +++ b/lib/SendStream.js @@ -71,6 +71,12 @@ const ERROR_RESPONSES = { 500: createHtmlDocument('Error', 'Internal Server Error') } +const validDotFilesOptions = [ + 'allow', + 'ignore', + 'deny' +] + /** * Initialize a `SendStream` with the given `path`. * @@ -105,10 +111,10 @@ function SendStream (req, path, options) { : true this._dotfiles = opts.dotfiles !== undefined - ? opts.dotfiles - : 'ignore' + ? validDotFilesOptions.indexOf(opts.dotfiles) + : 1 // 'ignore' - if (this._dotfiles !== 'ignore' && this._dotfiles !== 'allow' && this._dotfiles !== 'deny') { + if (this._dotfiles === -1) { throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"') } @@ -548,16 +554,25 @@ SendStream.prototype.pipe = function pipe (res) { } // dotfile handling - if (containsDotFile(parts)) { - debug('%s dotfile "%s"', this._dotfiles, path) + if ( + ( + debug.enabled || // if debugging is enabled, then check for all cases to log allow case + this._dotfiles !== 0 // if debugging is not enabled, then only check if 'deny' or 'ignore' is set + ) && + containsDotFile(parts) + ) { switch (this._dotfiles) { - case 'allow': + /* istanbul ignore next: unreachable, because NODE_DEBUG can not be set after process is running */ + case 0: // 'allow' + debug('allow dotfile "%s"', path) break - case 'deny': + case 2: // 'deny' + debug('deny dotfile "%s"', path) this.error(403) return res - case 'ignore': + case 1: // 'ignore' default: + debug('ignore dotfile "%s"', path) this.error(404) return res } diff --git a/lib/containsDotFile.js b/lib/containsDotFile.js index f19d5f4..c446aa0 100644 --- a/lib/containsDotFile.js +++ b/lib/containsDotFile.js @@ -11,13 +11,13 @@ * @api private */ function containsDotFile (parts) { - for (let i = 0; i < parts.length; i++) { - const part = parts[i] - if (part.length > 1 && part[0] === '.') { + for (let i = 0, il = parts.length; i < il; ++i) { + if (parts[i].length !== 1 && parts[i][0] === '.') { return true } } return false } -exports.containsDotFile = containsDotFile + +module.exports.containsDotFile = containsDotFile diff --git a/test/containsDotFile.test.js b/test/containsDotFile.test.js new file mode 100644 index 0000000..03e5f50 --- /dev/null +++ b/test/containsDotFile.test.js @@ -0,0 +1,18 @@ +'use strict' + +const { test } = require('tap') +const { containsDotFile } = require('../lib/containsDotFile') + +test('containsDotFile', function (t) { + const testCases = [ + ['/.github', true], + ['.github', true], + ['index.html', false], + ['./index.html', false] + ] + t.plan(testCases.length) + + for (let i = 0; i < testCases.length; ++i) { + t.strictSame(containsDotFile(testCases[i][0].split('/')), testCases[i][1], testCases[i][0]) + } +})