Skip to content

Commit 39ebdf4

Browse files
mcollinacemremengu
authored andcommitted
Use glob to avoid setting a wildcard route (#83)
* Use glob to avoid setting a wildcard route * removed spurious log * README update * remove useless replace for windows
1 parent f2f5113 commit 39ebdf4

File tree

4 files changed

+158
-6
lines changed

4 files changed

+158
-6
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ The following options are also supported and will be passed directly to the
7171
- [`lastModified`](https://www.npmjs.com/package/send#lastmodified)
7272
- [`maxAge`](https://www.npmjs.com/package/send#maxage)
7373

74+
#### `wildcard`
75+
76+
Default: `true`
77+
78+
If set to `true`, `fastify-static` adds a wildcard route to serve files.
79+
If set to `false`, `fastify-static` globs the filesystem for all defined
80+
files in the served folder, and just creates the routes needed for
81+
those.
82+
83+
The default options of https://www.npmjs.com/package/glob are applied
84+
for getting the file list.
85+
7486
#### Disable serving
7587

7688
If you'd just like to use the reply decorator and not serve whole directories automatically, you can simply pass the option `{ serve: false }`. This will prevent the plugin from serving everything under `root`.

index.js

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const path = require('path')
44
const statSync = require('fs').statSync
55
const { PassThrough } = require('readable-stream')
6+
const glob = require('glob')
67

78
const send = require('send')
89

@@ -91,18 +92,44 @@ function fastifyStatic (fastify, opts, next) {
9192
// Set the schema hide property if defined in opts or true by default
9293
const schema = { schema: { hide: typeof opts.schemaHide !== 'undefined' ? opts.schemaHide : true } }
9394

94-
if (opts.serve !== false) {
95-
fastify.get(prefix + '*', schema, function (req, reply) {
96-
pumpSendToReply(req, reply, '/' + req.params['*'])
97-
})
98-
}
99-
10095
if (opts.decorateReply !== false) {
10196
fastify.decorateReply('sendFile', function (filePath) {
10297
pumpSendToReply(this.request, this, filePath)
10398
})
10499
}
105100

101+
if (opts.serve !== false) {
102+
if (opts.wildcard === undefined || opts.wildcard === true) {
103+
fastify.get(prefix + '*', schema, function (req, reply) {
104+
pumpSendToReply(req, reply, '/' + req.params['*'])
105+
})
106+
} else {
107+
glob(path.join(sendOptions.root, '**/*'), function (err, files) {
108+
if (err) {
109+
return next(err)
110+
}
111+
for (let file of files) {
112+
file = file.replace(sendOptions.root, '')
113+
const route = (prefix + file).replace(/^\/\//, '/')
114+
fastify.get(route, schema, function (req, reply) {
115+
pumpSendToReply(req, reply, '/' + file)
116+
})
117+
118+
if (file.match(/index\.html$/)) {
119+
const route2 = route.replace(/index\.html$/, '')
120+
fastify.get(route2, schema, function (req, reply) {
121+
pumpSendToReply(req, reply, '/' + file)
122+
})
123+
}
124+
}
125+
next()
126+
})
127+
128+
// return early to avoid calling next afterwards
129+
return
130+
}
131+
}
132+
106133
next()
107134
}
108135

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"homepage": "https://github.com/fastify/fastify-static",
2828
"dependencies": {
2929
"fastify-plugin": "^1.2.0",
30+
"glob": "^7.1.3",
3031
"readable-stream": "^3.0.2",
3132
"send": "^0.16.0"
3233
},

test/static.test.js

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,3 +974,115 @@ t.test('register /static/ without schemaHide', t => {
974974
})
975975
})
976976
})
977+
978+
t.test('register with wildcard false', t => {
979+
t.plan(8)
980+
981+
const pluginOptions = {
982+
root: path.join(__dirname, '/static'),
983+
wildcard: false
984+
}
985+
const fastify = Fastify()
986+
fastify.register(fastifyStatic, pluginOptions)
987+
988+
fastify.get('/*', (request, reply) => {
989+
reply.send({ hello: 'world' })
990+
})
991+
992+
t.tearDown(fastify.close.bind(fastify))
993+
994+
fastify.listen(0, err => {
995+
t.error(err)
996+
997+
fastify.server.unref()
998+
999+
t.test('/index.html', t => {
1000+
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
1001+
simple.concat({
1002+
method: 'GET',
1003+
url: 'http://localhost:' + fastify.server.address().port + '/index.html'
1004+
}, (err, response, body) => {
1005+
t.error(err)
1006+
t.strictEqual(response.statusCode, 200)
1007+
t.strictEqual(body.toString(), indexContent)
1008+
genericResponseChecks(t, response)
1009+
})
1010+
})
1011+
1012+
t.test('/index.css', t => {
1013+
t.plan(2 + GENERIC_RESPONSE_CHECK_COUNT)
1014+
simple.concat({
1015+
method: 'GET',
1016+
url: 'http://localhost:' + fastify.server.address().port + '/index.css'
1017+
}, (err, response, body) => {
1018+
t.error(err)
1019+
t.strictEqual(response.statusCode, 200)
1020+
genericResponseChecks(t, response)
1021+
})
1022+
})
1023+
1024+
t.test('/', t => {
1025+
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
1026+
simple.concat({
1027+
method: 'GET',
1028+
url: 'http://localhost:' + fastify.server.address().port
1029+
}, (err, response, body) => {
1030+
t.error(err)
1031+
t.strictEqual(response.statusCode, 200)
1032+
t.strictEqual(body.toString(), indexContent)
1033+
genericResponseChecks(t, response)
1034+
})
1035+
})
1036+
1037+
t.test('/not-defined', t => {
1038+
t.plan(3)
1039+
simple.concat({
1040+
method: 'GET',
1041+
url: 'http://localhost:' + fastify.server.address().port + '/not-defined'
1042+
}, (err, response, body) => {
1043+
t.error(err)
1044+
t.strictEqual(response.statusCode, 200)
1045+
t.deepEqual(JSON.parse(body), { hello: 'world' })
1046+
})
1047+
})
1048+
1049+
t.test('/deep/path/for/test/purpose/foo.html', t => {
1050+
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
1051+
simple.concat({
1052+
method: 'GET',
1053+
url: 'http://localhost:' + fastify.server.address().port + '/deep/path/for/test/purpose/foo.html'
1054+
}, (err, response, body) => {
1055+
t.error(err)
1056+
t.strictEqual(response.statusCode, 200)
1057+
t.strictEqual(body.toString(), deepContent)
1058+
genericResponseChecks(t, response)
1059+
})
1060+
})
1061+
1062+
t.test('/deep/path/for/test/', t => {
1063+
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
1064+
simple.concat({
1065+
method: 'GET',
1066+
url: 'http://localhost:' + fastify.server.address().port + '/deep/path/for/test/'
1067+
}, (err, response, body) => {
1068+
t.error(err)
1069+
t.strictEqual(response.statusCode, 200)
1070+
t.strictEqual(body.toString(), innerIndex)
1071+
genericResponseChecks(t, response)
1072+
})
1073+
})
1074+
1075+
t.test('/../index.js', t => {
1076+
t.plan(3)
1077+
simple.concat({
1078+
method: 'GET',
1079+
url: 'http://localhost:' + fastify.server.address().port + '/../index.js',
1080+
followRedirect: false
1081+
}, (err, response, body) => {
1082+
t.error(err)
1083+
t.strictEqual(response.statusCode, 200)
1084+
t.deepEqual(JSON.parse(body), { hello: 'world' })
1085+
})
1086+
})
1087+
})
1088+
})

0 commit comments

Comments
 (0)