Skip to content

Commit 377b974

Browse files
committed
Add option to filter files
1 parent c7cfa9f commit 377b974

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ for getting the file list.
135135
This option cannot be set to `false` with `redirect` set to `true` on a server
136136
with `ignoreTrailingSlash` set to `true`.
137137

138+
#### `allowedPath`
139+
140+
Default: `(pathname, root) => true`
141+
142+
This function allows filtering the served files.
143+
If the function returns `true`, the file will be served.
144+
If the function returns `false`, Fastify's 404 handler will be called.
145+
138146
#### `list`
139147

140148
Default: `undefined`

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export interface FastifyStaticOptions {
4141
redirect?: boolean;
4242
wildcard?: boolean | string;
4343
list?: boolean | ListOptions;
44+
allowedPath?: (pathName: string, root?: string) => boolean;
4445

4546
// Passed on to `send`
4647
acceptRanges?: boolean;

index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ const globPromise = util.promisify(glob)
1212

1313
const dirList = require('./lib/dirList')
1414

15+
function allowAllPaths () {
16+
return true
17+
}
18+
1519
async function fastifyStatic (fastify, opts) {
1620
checkRootPathForErrors(fastify, opts.root)
1721

@@ -39,6 +43,8 @@ async function fastifyStatic (fastify, opts) {
3943
maxAge: opts.maxAge
4044
}
4145

46+
const allowedPath = opts.allowedPath || allowAllPaths
47+
4248
function pumpSendToReply (request, reply, pathname, rootPath, rootPathOffset = 0) {
4349
const options = Object.assign({}, sendOptions)
4450

@@ -50,6 +56,10 @@ async function fastifyStatic (fastify, opts) {
5056
}
5157
}
5258

59+
if (!allowedPath(pathname, options.root)) {
60+
return reply.callNotFound()
61+
}
62+
5363
const stream = send(request.raw, pathname, options)
5464
let resolvedFilename
5565
stream.on('file', function (file) {

test/static.test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,48 @@ t.test('sendFile disabled', t => {
819819
})
820820
})
821821

822+
t.test('allowedPath option', t => {
823+
t.plan(3)
824+
825+
const pluginOptions = {
826+
root: path.join(__dirname, '/static'),
827+
allowedPath: (pathName) => pathName !== '/foobar.html'
828+
}
829+
const fastify = Fastify()
830+
fastify.register(fastifyStatic, pluginOptions)
831+
832+
fastify.listen(0, err => {
833+
t.error(err)
834+
835+
fastify.server.unref()
836+
837+
t.test('/foobar.html not found', t => {
838+
t.plan(2 + GENERIC_ERROR_RESPONSE_CHECK_COUNT)
839+
simple.concat({
840+
method: 'GET',
841+
url: 'http://localhost:' + fastify.server.address().port + '/foobar.html',
842+
followRedirect: false
843+
}, (err, response, body) => {
844+
t.error(err)
845+
t.strictEqual(response.statusCode, 404)
846+
genericErrorResponseChecks(t, response)
847+
})
848+
})
849+
850+
t.test('/index.css found', t => {
851+
t.plan(2)
852+
simple.concat({
853+
method: 'GET',
854+
url: 'http://localhost:' + fastify.server.address().port + '/index.css',
855+
followRedirect: false
856+
}, (err, response, body) => {
857+
t.error(err)
858+
t.strictEqual(response.statusCode, 200)
859+
})
860+
})
861+
})
862+
})
863+
822864
t.test('prefix default', t => {
823865
t.plan(1)
824866
const pluginOptions = { root: path.join(__dirname, 'static') }

0 commit comments

Comments
 (0)