@fastify/static 6.10.0 → 6.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +5 -0
- package/example/public/images/sample.jpg +0 -0
- package/index.js +28 -1
- package/package.json +2 -2
- package/test/content-type/binary +0 -0
- package/test/content-type/binary.br +1 -0
- package/test/content-type/index.css +0 -0
- package/test/content-type/index.css.br +1 -0
- package/test/content-type/index.html +5 -0
- package/test/content-type/index.html.br +0 -0
- package/test/content-type/sample.jpg +0 -0
- package/test/content-type/sample.jpg.br +0 -0
- package/test/content-type/test.txt +0 -0
- package/test/content-type/test.txt.br +1 -0
- package/test/content-type.test.js +174 -0
- package/test/static.test.js +47 -0
package/.github/workflows/ci.yml
CHANGED
|
Binary file
|
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const path = require('path')
|
|
4
|
+
const url = require('url')
|
|
4
5
|
const statSync = require('fs').statSync
|
|
5
6
|
const { PassThrough } = require('readable-stream')
|
|
6
7
|
const glob = require('glob')
|
|
@@ -11,9 +12,12 @@ const util = require('util')
|
|
|
11
12
|
const globPromise = util.promisify(glob)
|
|
12
13
|
const encodingNegotiator = require('@fastify/accept-negotiator')
|
|
13
14
|
|
|
15
|
+
send.mime.default_type = 'application/octet-stream'
|
|
16
|
+
|
|
14
17
|
const dirList = require('./lib/dirList')
|
|
15
18
|
|
|
16
19
|
async function fastifyStatic (fastify, opts) {
|
|
20
|
+
opts.root = normalizeRoot(opts.root)
|
|
17
21
|
checkRootPathForErrors(fastify, opts.root)
|
|
18
22
|
|
|
19
23
|
const setHeaders = opts.setHeaders
|
|
@@ -394,6 +398,29 @@ async function fastifyStatic (fastify, opts) {
|
|
|
394
398
|
pumpSendToReply(req, reply, file, rootPath)
|
|
395
399
|
}
|
|
396
400
|
}
|
|
401
|
+
function normalizeRoot (root) {
|
|
402
|
+
if (root === undefined) {
|
|
403
|
+
return root
|
|
404
|
+
}
|
|
405
|
+
if (root instanceof URL && root.protocol === 'file:') {
|
|
406
|
+
return url.fileURLToPath(root)
|
|
407
|
+
}
|
|
408
|
+
if (Array.isArray(root)) {
|
|
409
|
+
const result = []
|
|
410
|
+
for (let i = 0, il = root.length; i < il; ++i) {
|
|
411
|
+
if (root[i] instanceof URL && root[i].protocol === 'file:') {
|
|
412
|
+
result.push(url.fileURLToPath(root[i]))
|
|
413
|
+
} else {
|
|
414
|
+
result.push(root[i])
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return result
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return root
|
|
422
|
+
}
|
|
423
|
+
|
|
397
424
|
function checkRootPathForErrors (fastify, rootPath) {
|
|
398
425
|
if (rootPath === undefined) {
|
|
399
426
|
throw new Error('"root" option is required')
|
|
@@ -451,7 +478,7 @@ function checkPath (fastify, rootPath) {
|
|
|
451
478
|
const supportedEncodings = ['br', 'gzip', 'deflate']
|
|
452
479
|
|
|
453
480
|
function getContentType (path) {
|
|
454
|
-
const type = send.mime.getType(path)
|
|
481
|
+
const type = send.mime.getType(path) || send.mime.default_type
|
|
455
482
|
|
|
456
483
|
if (!send.isUtf8MimeType(type)) {
|
|
457
484
|
return type
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastify/static",
|
|
3
|
-
"version": "6.10.
|
|
3
|
+
"version": "6.10.2",
|
|
4
4
|
"description": "Plugin for serving static files as fast as possible.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@fastify/compress": "^6.0.0",
|
|
42
42
|
"@fastify/pre-commit": "^2.0.2",
|
|
43
|
-
"@types/node": "^
|
|
43
|
+
"@types/node": "^20.1.0",
|
|
44
44
|
"@typescript-eslint/eslint-plugin": "^2.29.0",
|
|
45
45
|
"@typescript-eslint/parser": "^2.29.0",
|
|
46
46
|
"concat-stream": "^2.0.0",
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
�
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
�
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
�
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/* eslint n/no-deprecated-api: "off" */
|
|
4
|
+
|
|
5
|
+
const path = require('path')
|
|
6
|
+
const { test } = require('tap')
|
|
7
|
+
const simple = require('simple-get')
|
|
8
|
+
const Fastify = require('fastify')
|
|
9
|
+
|
|
10
|
+
const fastifyStatic = require('../')
|
|
11
|
+
|
|
12
|
+
test('register /content-type', t => {
|
|
13
|
+
t.plan(6)
|
|
14
|
+
|
|
15
|
+
const pluginOptions = {
|
|
16
|
+
root: path.join(__dirname, '/content-type'),
|
|
17
|
+
prefix: '/content-type'
|
|
18
|
+
}
|
|
19
|
+
const fastify = Fastify()
|
|
20
|
+
fastify.register(fastifyStatic, pluginOptions)
|
|
21
|
+
|
|
22
|
+
t.teardown(fastify.close.bind(fastify))
|
|
23
|
+
|
|
24
|
+
fastify.listen({ port: 0 }, (err) => {
|
|
25
|
+
t.error(err)
|
|
26
|
+
|
|
27
|
+
fastify.server.unref()
|
|
28
|
+
|
|
29
|
+
t.test('/content-type/index.html', (t) => {
|
|
30
|
+
t.plan(2)
|
|
31
|
+
simple.concat({
|
|
32
|
+
method: 'GET',
|
|
33
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/index.html'
|
|
34
|
+
}, (err, response) => {
|
|
35
|
+
t.error(err)
|
|
36
|
+
t.equal(response.headers['content-type'], 'text/html; charset=UTF-8')
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
t.test('/content-type/index.css', (t) => {
|
|
41
|
+
t.plan(2)
|
|
42
|
+
simple.concat({
|
|
43
|
+
method: 'GET',
|
|
44
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/index.css'
|
|
45
|
+
}, (err, response) => {
|
|
46
|
+
t.error(err)
|
|
47
|
+
t.equal(response.headers['content-type'], 'text/css; charset=UTF-8')
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
t.test('/content-type/sample.jpg', (t) => {
|
|
52
|
+
t.plan(2)
|
|
53
|
+
simple.concat({
|
|
54
|
+
method: 'GET',
|
|
55
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/sample.jpg'
|
|
56
|
+
}, (err, response) => {
|
|
57
|
+
t.error(err)
|
|
58
|
+
t.equal(response.headers['content-type'], 'image/jpeg')
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
t.test('/content-type/test.txt', (t) => {
|
|
63
|
+
t.plan(2)
|
|
64
|
+
simple.concat({
|
|
65
|
+
method: 'GET',
|
|
66
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/test.txt'
|
|
67
|
+
}, (err, response) => {
|
|
68
|
+
t.error(err)
|
|
69
|
+
t.equal(response.headers['content-type'], 'text/plain; charset=UTF-8')
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
t.test('/content-type/binary', (t) => {
|
|
74
|
+
t.plan(2)
|
|
75
|
+
simple.concat({
|
|
76
|
+
method: 'GET',
|
|
77
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/binary'
|
|
78
|
+
}, (err, response) => {
|
|
79
|
+
t.error(err)
|
|
80
|
+
t.equal(response.headers['content-type'], 'application/octet-stream')
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
test('register /content-type preCompressed', t => {
|
|
87
|
+
t.plan(6)
|
|
88
|
+
|
|
89
|
+
const pluginOptions = {
|
|
90
|
+
root: path.join(__dirname, '/content-type'),
|
|
91
|
+
prefix: '/content-type',
|
|
92
|
+
preCompressed: true
|
|
93
|
+
}
|
|
94
|
+
const fastify = Fastify()
|
|
95
|
+
fastify.register(fastifyStatic, pluginOptions)
|
|
96
|
+
|
|
97
|
+
t.teardown(fastify.close.bind(fastify))
|
|
98
|
+
|
|
99
|
+
fastify.listen({ port: 0 }, (err) => {
|
|
100
|
+
t.error(err)
|
|
101
|
+
|
|
102
|
+
fastify.server.unref()
|
|
103
|
+
|
|
104
|
+
t.test('/content-type/index.html', (t) => {
|
|
105
|
+
t.plan(2)
|
|
106
|
+
simple.concat({
|
|
107
|
+
method: 'GET',
|
|
108
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/index.html',
|
|
109
|
+
headers: {
|
|
110
|
+
'accept-encoding': 'gzip, deflate, br'
|
|
111
|
+
}
|
|
112
|
+
}, (err, response) => {
|
|
113
|
+
t.error(err)
|
|
114
|
+
t.equal(response.headers['content-type'], 'text/html; charset=UTF-8')
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
t.test('/content-type/index.css', (t) => {
|
|
119
|
+
t.plan(2)
|
|
120
|
+
simple.concat({
|
|
121
|
+
method: 'GET',
|
|
122
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/index.css',
|
|
123
|
+
headers: {
|
|
124
|
+
'accept-encoding': 'gzip, deflate, br'
|
|
125
|
+
}
|
|
126
|
+
}, (err, response) => {
|
|
127
|
+
t.error(err)
|
|
128
|
+
t.equal(response.headers['content-type'], 'text/css; charset=UTF-8')
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
t.test('/content-type/sample.jpg', (t) => {
|
|
133
|
+
t.plan(2)
|
|
134
|
+
simple.concat({
|
|
135
|
+
method: 'GET',
|
|
136
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/sample.jpg',
|
|
137
|
+
headers: {
|
|
138
|
+
'accept-encoding': 'gzip, deflate, br'
|
|
139
|
+
}
|
|
140
|
+
}, (err, response) => {
|
|
141
|
+
t.error(err)
|
|
142
|
+
t.equal(response.headers['content-type'], 'image/jpeg')
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
t.test('/content-type/test.txt', (t) => {
|
|
147
|
+
t.plan(2)
|
|
148
|
+
simple.concat({
|
|
149
|
+
method: 'GET',
|
|
150
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/test.txt',
|
|
151
|
+
headers: {
|
|
152
|
+
'accept-encoding': 'gzip, deflate, br'
|
|
153
|
+
}
|
|
154
|
+
}, (err, response) => {
|
|
155
|
+
t.error(err)
|
|
156
|
+
t.equal(response.headers['content-type'], 'text/plain; charset=UTF-8')
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
t.test('/content-type/binary', (t) => {
|
|
161
|
+
t.plan(2)
|
|
162
|
+
simple.concat({
|
|
163
|
+
method: 'GET',
|
|
164
|
+
url: 'http://localhost:' + fastify.server.address().port + '/content-type/binary',
|
|
165
|
+
headers: {
|
|
166
|
+
'accept-encoding': 'gzip, deflate, br'
|
|
167
|
+
}
|
|
168
|
+
}, (err, response) => {
|
|
169
|
+
t.error(err)
|
|
170
|
+
t.equal(response.headers['content-type'], 'application/octet-stream')
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
})
|
|
174
|
+
})
|
package/test/static.test.js
CHANGED
|
@@ -3756,3 +3756,50 @@ t.test(
|
|
|
3756
3756
|
t.end()
|
|
3757
3757
|
}
|
|
3758
3758
|
)
|
|
3759
|
+
t.test(
|
|
3760
|
+
'converts URL to path',
|
|
3761
|
+
async (t) => {
|
|
3762
|
+
t.plan(2 + GENERIC_RESPONSE_CHECK_COUNT)
|
|
3763
|
+
const pluginOptions = {
|
|
3764
|
+
root: url.pathToFileURL(path.join(__dirname, '/static'))
|
|
3765
|
+
}
|
|
3766
|
+
|
|
3767
|
+
const fastify = Fastify()
|
|
3768
|
+
|
|
3769
|
+
fastify.register(fastifyStatic, pluginOptions)
|
|
3770
|
+
const response = await fastify.inject({
|
|
3771
|
+
method: 'GET',
|
|
3772
|
+
url: 'foobar.html',
|
|
3773
|
+
headers: {
|
|
3774
|
+
'accept-encoding': '*, *'
|
|
3775
|
+
}
|
|
3776
|
+
})
|
|
3777
|
+
genericResponseChecks(t, response)
|
|
3778
|
+
t.equal(response.statusCode, 200)
|
|
3779
|
+
t.same(response.body, foobarContent)
|
|
3780
|
+
}
|
|
3781
|
+
)
|
|
3782
|
+
|
|
3783
|
+
t.test(
|
|
3784
|
+
'converts array of URLs to path, contains string path',
|
|
3785
|
+
async (t) => {
|
|
3786
|
+
t.plan(2 + GENERIC_RESPONSE_CHECK_COUNT)
|
|
3787
|
+
const pluginOptions = {
|
|
3788
|
+
root: [url.pathToFileURL(path.join(__dirname, '/static')), path.join(__dirname, 'static-dotfiles'), url.pathToFileURL(path.join(__dirname, '/static-pre-compressed'))]
|
|
3789
|
+
}
|
|
3790
|
+
|
|
3791
|
+
const fastify = Fastify()
|
|
3792
|
+
|
|
3793
|
+
fastify.register(fastifyStatic, pluginOptions)
|
|
3794
|
+
const response = await fastify.inject({
|
|
3795
|
+
method: 'GET',
|
|
3796
|
+
url: 'foobar.html',
|
|
3797
|
+
headers: {
|
|
3798
|
+
'accept-encoding': '*, *'
|
|
3799
|
+
}
|
|
3800
|
+
})
|
|
3801
|
+
genericResponseChecks(t, response)
|
|
3802
|
+
t.equal(response.statusCode, 200)
|
|
3803
|
+
t.same(response.body, foobarContent)
|
|
3804
|
+
}
|
|
3805
|
+
)
|