Skip to content

Commit 2e3ae43

Browse files
committed
Add globIgnore option
Signed-off-by: Matteo Collina <hello@matteocollina.com>
1 parent 7c0c25f commit 2e3ae43

File tree

9 files changed

+94
-2
lines changed

9 files changed

+94
-2
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,14 @@ are applied for getting the file list.
233233
234234
This option cannot be `false` if `redirect` is `true` and `ignoreTrailingSlash` is `true`.
235235
236+
#### `globIgnore`
237+
238+
Default: `undefined`
239+
240+
This is passed to [`glob`](https://www.npmjs.com/package/glob)
241+
as the `ignore` option. It can be used to ignore files or directories
242+
when using the `wildcard: false` option.
243+
236244
#### `allowedPath`
237245
238246
Default: `(pathName, root, request) => true`

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
'use strict'
1+
'unse strict'
22

33
const path = require('node:path')
44
const { fileURLToPath } = require('node:url')
@@ -135,7 +135,7 @@ async function fastifyStatic (fastify, opts) {
135135
rootPath = rootPath.split(path.win32.sep).join(path.posix.sep)
136136
!rootPath.endsWith('/') && (rootPath += '/')
137137
const files = await glob('**/**', {
138-
cwd: rootPath, absolute: false, follow: true, nodir: true, dot: opts.serveDotFiles
138+
cwd: rootPath, absolute: false, follow: true, nodir: true, dot: opts.serveDotFiles, ignore: opts.globIgnore
139139
})
140140

141141
for (let file of files) {

test/static-filtered/bar.private

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bar
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<html>
2+
<body>baz</body>
3+
</html>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
baz

test/static-filtered/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<html>
2+
<body>index2</body>
3+
</html>

test/static.test.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3669,3 +3669,77 @@ test('register /static/ with custom log level', async t => {
36693669
t.assert.deepStrictEqual(response2.status, 304)
36703670
})
36713671
})
3672+
3673+
test('register with wildcard false and globIgnore', async t => {
3674+
t.plan(5)
3675+
3676+
const indexContent = fs
3677+
.readFileSync('./test/static-filtered/index.html')
3678+
.toString('utf8')
3679+
3680+
const deepContent = fs
3681+
.readFileSync('./test/static-filtered/deep/path/to/baz.html')
3682+
.toString('utf8')
3683+
3684+
const pluginOptions = {
3685+
root: path.join(__dirname, '/static-filtered'),
3686+
wildcard: false,
3687+
globIgnore: ['**/*.private']
3688+
}
3689+
const fastify = Fastify()
3690+
fastify.register(fastifyStatic, pluginOptions)
3691+
3692+
t.after(() => fastify.close())
3693+
3694+
await fastify.listen({ port: 0 })
3695+
3696+
fastify.server.unref()
3697+
3698+
await t.test('/index.html', async t => {
3699+
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
3700+
3701+
const response = await fetch('http://localhost:' + fastify.server.address().port + '/index.html')
3702+
t.assert.ok(response.ok)
3703+
t.assert.deepStrictEqual(response.status, 200)
3704+
t.assert.deepStrictEqual(await response.text(), indexContent)
3705+
genericResponseChecks(t, response)
3706+
})
3707+
3708+
await t.test('/bar.private', async t => {
3709+
t.plan(2)
3710+
3711+
const response = await fetch('http://localhost:' + fastify.server.address().port + '/bar.private')
3712+
t.assert.ok(!response.ok)
3713+
t.assert.deepStrictEqual(response.status, 404)
3714+
await response.text()
3715+
})
3716+
3717+
await t.test('/', async (t) => {
3718+
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
3719+
3720+
const response = await fetch('http://localhost:' + fastify.server.address().port)
3721+
t.assert.ok(response.ok)
3722+
t.assert.deepStrictEqual(response.status, 200)
3723+
t.assert.deepStrictEqual(await response.text(), indexContent)
3724+
genericResponseChecks(t, response)
3725+
})
3726+
3727+
await t.test('/deep/path/to/baz.html', async (t) => {
3728+
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
3729+
3730+
const response = await fetch('http://localhost:' + fastify.server.address().port + '/deep/path/to/baz.html')
3731+
t.assert.ok(response.ok)
3732+
t.assert.deepStrictEqual(response.status, 200)
3733+
t.assert.deepStrictEqual(await response.text(), deepContent)
3734+
genericResponseChecks(t, response)
3735+
})
3736+
3737+
await t.test('/deep/path/to/baz.private', async (t) => {
3738+
t.plan(2)
3739+
3740+
const response = await fetch('http://localhost:' + fastify.server.address().port + '/deep/path/to/baz.private')
3741+
t.assert.ok(!response.ok)
3742+
t.assert.deepStrictEqual(response.status, 404)
3743+
await response.text()
3744+
})
3745+
})

types/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ declare namespace fastifyStatic {
9494
setHeaders?: (res: SetHeadersResponse, path: string, stat: Stats) => void;
9595
redirect?: boolean;
9696
wildcard?: boolean;
97+
globIgnore?: string[];
9798
list?: boolean | ListOptionsJsonFormat | ListOptionsHtmlFormat;
9899
allowedPath?: (pathName: string, root: string, request: FastifyRequest) => boolean;
99100
/**

types/index.test-d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const options: FastifyStaticOptions = {
5050
schemaHide: true,
5151
serve: true,
5252
wildcard: true,
53+
globIgnore: ['**/*.private'],
5354
list: false,
5455
setHeaders: (res, path, stat) => {
5556
expectType<string>(res.filename)

0 commit comments

Comments
 (0)