From c2fd230b52365d9c0af137d6ac4adfb71b37cc52 Mon Sep 17 00:00:00 2001 From: Jenny Eckstein Date: Sun, 19 Apr 2020 13:23:58 -0400 Subject: [PATCH 1/6] Add flag to avoid trailing slash in prefix --- README.md | 6 ++++++ index.d.ts | 1 + index.js | 7 ++++++- test/static.test.js | 9 ++++++--- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index df223e4..e791dca 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,12 @@ Default: `'/'` A URL path prefix used to create a virtual mount path for the static directory. +### `prefixAvoidTrailingSlash` + +Default: `false` + +If set to false prefix will get trailing "/" at the end. If set to true, prefix will not append "/" to prefix. + #### `schemaHide` Default: `true` diff --git a/index.d.ts b/index.d.ts index 2f95654..cad0d7f 100644 --- a/index.d.ts +++ b/index.d.ts @@ -24,6 +24,7 @@ declare function fastifyStatic(): fastify.Plugin< { root: string; prefix?: string; + prefixAvoidTrailingSlash?: boolean; serve?: boolean; decorateReply?: boolean; schemaHide?: boolean; diff --git a/index.js b/index.js index fe3c26f..86df09f 100644 --- a/index.js +++ b/index.js @@ -107,7 +107,12 @@ function fastifyStatic (fastify, opts, next) { } if (opts.prefix === undefined) opts.prefix = '/' - const prefix = opts.prefix[opts.prefix.length - 1] === '/' ? opts.prefix : (opts.prefix + '/') + + let prefix = opts.prefix + + if (!opts.prefixAvoidTrailingSlash) { + prefix = opts.prefix[opts.prefix.length - 1] === '/' ? opts.prefix : (opts.prefix + '/') + } // Set the schema hide property if defined in opts or true by default const schema = { schema: { hide: typeof opts.schemaHide !== 'undefined' ? opts.schemaHide : true } } diff --git a/test/static.test.js b/test/static.test.js index f82a06b..78cff37 100644 --- a/test/static.test.js +++ b/test/static.test.js @@ -38,7 +38,8 @@ t.test('register /static', t => { const pluginOptions = { root: path.join(__dirname, '/static'), - prefix: '/static' + prefix: '/static', + prefixAvoidTrailingSlash: true } const fastify = Fastify() fastify.register(fastifyStatic, pluginOptions) @@ -89,13 +90,15 @@ t.test('register /static', t => { }) t.test('/static', t => { - t.plan(2) + t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT) simple.concat({ method: 'GET', url: 'http://localhost:' + fastify.server.address().port + '/static' }, (err, response, body) => { t.error(err) - t.strictEqual(response.statusCode, 404) + t.strictEqual(response.statusCode, 200) + t.strictEqual(body.toString(), indexContent) + genericResponseChecks(t, response) }) }) From 1fccbae0eeebf8d174ae816245854de4bcd50386 Mon Sep 17 00:00:00 2001 From: Jenny Eckstein Date: Sun, 19 Apr 2020 19:52:20 -0400 Subject: [PATCH 2/6] Add separate block for prefixAvoidTrailingSlash tests --- test/static.test.js | 148 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/test/static.test.js b/test/static.test.js index 78cff37..3c5cb6b 100644 --- a/test/static.test.js +++ b/test/static.test.js @@ -33,7 +33,7 @@ function genericErrorResponseChecks (t, response) { t.ok(response.headers.date) } -t.test('register /static', t => { +t.test('register /static prefixAvoidTrailingSlash', t => { t.plan(11) const pluginOptions = { @@ -128,6 +128,152 @@ t.test('register /static', t => { }) }) + t.test('/static/this/path/for/test', t => { + t.plan(2 + GENERIC_ERROR_RESPONSE_CHECK_COUNT) + simple.concat({ + method: 'GET', + url: 'http://localhost:' + fastify.server.address().port + '/static/this/path/for/test', + followRedirect: false + }, (err, response, body) => { + console.log('JENNY ERR:', response) + t.error(err) + t.strictEqual(response.statusCode, 404) + genericErrorResponseChecks(t, response) + }) + }) + + t.test('/static/this/path/doesnt/exist.html', t => { + t.plan(2 + GENERIC_ERROR_RESPONSE_CHECK_COUNT) + simple.concat({ + method: 'GET', + url: 'http://localhost:' + fastify.server.address().port + '/static/this/path/doesnt/exist.html', + followRedirect: false + }, (err, response, body) => { + t.error(err) + t.strictEqual(response.statusCode, 404) + genericErrorResponseChecks(t, response) + }) + }) + + t.test('/static/../index.js', t => { + t.plan(2 + GENERIC_ERROR_RESPONSE_CHECK_COUNT) + simple.concat({ + method: 'GET', + url: 'http://localhost:' + fastify.server.address().port + '/static/../index.js', + followRedirect: false + }, (err, response, body) => { + t.error(err) + t.strictEqual(response.statusCode, 403) + genericErrorResponseChecks(t, response) + }) + }) + + t.test('file not exposed outside of the plugin', t => { + t.plan(2) + simple.concat({ + method: 'GET', + // foobar is in static + url: 'http://localhost:' + fastify.server.address().port + '/foobar.html' + }, (err, response, body) => { + t.error(err) + t.strictEqual(response.statusCode, 404) + }) + }) + }) +}) + +t.test('register /static', t => { + t.plan(11) + + const pluginOptions = { + root: path.join(__dirname, '/static'), + prefix: '/static' + } + const fastify = Fastify() + fastify.register(fastifyStatic, pluginOptions) + + t.tearDown(fastify.close.bind(fastify)) + + fastify.listen(0, err => { + t.error(err) + + fastify.server.unref() + + t.test('/static/index.html', t => { + t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT) + simple.concat({ + method: 'GET', + url: 'http://localhost:' + fastify.server.address().port + '/static/index.html' + }, (err, response, body) => { + t.error(err) + t.strictEqual(response.statusCode, 200) + t.strictEqual(body.toString(), indexContent) + genericResponseChecks(t, response) + }) + }) + + t.test('/static/index.css', t => { + t.plan(2 + GENERIC_RESPONSE_CHECK_COUNT) + simple.concat({ + method: 'GET', + url: 'http://localhost:' + fastify.server.address().port + '/static/index.css' + }, (err, response, body) => { + t.error(err) + t.strictEqual(response.statusCode, 200) + genericResponseChecks(t, response) + }) + }) + + t.test('/static/', t => { + t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT) + simple.concat({ + method: 'GET', + url: 'http://localhost:' + fastify.server.address().port + '/static/' + }, (err, response, body) => { + t.error(err) + t.strictEqual(response.statusCode, 200) + t.strictEqual(body.toString(), indexContent) + genericResponseChecks(t, response) + }) + }) + + t.test('/static', t => { + t.plan(2) + simple.concat({ + method: 'GET', + url: 'http://localhost:' + fastify.server.address().port + '/static' + }, (err, response, body) => { + t.error(err) + t.strictEqual(response.statusCode, 404) + }) + }) + + t.test('/static/deep/path/for/test/purpose/foo.html', t => { + t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT) + simple.concat({ + method: 'GET', + url: 'http://localhost:' + fastify.server.address().port + '/static/deep/path/for/test/purpose/foo.html' + }, (err, response, body) => { + t.error(err) + t.strictEqual(response.statusCode, 200) + t.strictEqual(body.toString(), deepContent) + genericResponseChecks(t, response) + }) + }) + + t.test('/static/deep/path/for/test/', t => { + t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT) + simple.concat({ + method: 'GET', + url: 'http://localhost:' + fastify.server.address().port + '/static/deep/path/for/test/' + }, (err, response, body) => { + t.error(err) + t.strictEqual(response.statusCode, 200) + t.strictEqual(body.toString(), innerIndex) + genericResponseChecks(t, response) + }) + }) + t.test('/static/this/path/for/test', t => { t.plan(2 + GENERIC_ERROR_RESPONSE_CHECK_COUNT) simple.concat({ From bafa74c8bd84fc80cb37f50ea92ebc2e3b6ce472 Mon Sep 17 00:00:00 2001 From: Jenny Eckstein Date: Sun, 19 Apr 2020 19:57:57 -0400 Subject: [PATCH 3/6] Remove debug statement --- test/static.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/static.test.js b/test/static.test.js index 3c5cb6b..721afa3 100644 --- a/test/static.test.js +++ b/test/static.test.js @@ -135,7 +135,6 @@ t.test('register /static prefixAvoidTrailingSlash', t => { url: 'http://localhost:' + fastify.server.address().port + '/static/this/path/for/test', followRedirect: false }, (err, response, body) => { - console.log('JENNY ERR:', response) t.error(err) t.strictEqual(response.statusCode, 404) genericErrorResponseChecks(t, response) From ed2ee9e69fb0ca9cf3dd1f3db3548f7c8e407e41 Mon Sep 17 00:00:00 2001 From: Jenny Eckstein Date: Mon, 20 Apr 2020 09:06:42 -0400 Subject: [PATCH 4/6] Add prefixAvoidTrailingSlash to options in type --- test/types/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/types/index.ts b/test/types/index.ts index da65019..f4150d1 100644 --- a/test/types/index.ts +++ b/test/types/index.ts @@ -17,6 +17,7 @@ const options = { lastModified: true, maxAge: '', prefix: '', + prefixAvoidTrailingSlash: false, root: '', schemaHide: true, serve: true, From 9f8657d961c3456c80476d88000c01baad4b3745 Mon Sep 17 00:00:00 2001 From: Jenny Eckstein Date: Mon, 20 Apr 2020 10:28:28 -0400 Subject: [PATCH 5/6] Create npmpublish.yml --- .github/workflows/npmpublish.yml | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/npmpublish.yml diff --git a/.github/workflows/npmpublish.yml b/.github/workflows/npmpublish.yml new file mode 100644 index 0000000..861e372 --- /dev/null +++ b/.github/workflows/npmpublish.yml @@ -0,0 +1,47 @@ +# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created +# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages + +name: Node.js Package + +on: + release: + types: [created] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12 + - run: npm ci + - run: npm test + + publish-npm: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12 + registry-url: https://registry.npmjs.org/ + - run: npm ci + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.npm_token}} + + publish-gpr: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12 + registry-url: https://npm.pkg.github.com/ + - run: npm ci + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} From 3a1ddbdb502fb045239f3d4e662a6551294e9389 Mon Sep 17 00:00:00 2001 From: Jenny Eckstein Date: Mon, 20 Apr 2020 10:30:34 -0400 Subject: [PATCH 6/6] Revert "Create npmpublish.yml" This reverts commit 9f8657d961c3456c80476d88000c01baad4b3745. --- .github/workflows/npmpublish.yml | 47 -------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 .github/workflows/npmpublish.yml diff --git a/.github/workflows/npmpublish.yml b/.github/workflows/npmpublish.yml deleted file mode 100644 index 861e372..0000000 --- a/.github/workflows/npmpublish.yml +++ /dev/null @@ -1,47 +0,0 @@ -# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created -# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages - -name: Node.js Package - -on: - release: - types: [created] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 12 - - run: npm ci - - run: npm test - - publish-npm: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 12 - registry-url: https://registry.npmjs.org/ - - run: npm ci - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{secrets.npm_token}} - - publish-gpr: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 12 - registry-url: https://npm.pkg.github.com/ - - run: npm ci - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}