Skip to content

Commit

Permalink
Merge branch 'update-next' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
jsumners committed Jul 3, 2024
2 parents 60504fa + 4af5c34 commit 691606c
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 19 deletions.
15 changes: 11 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,13 @@ async function fastifyStatic (fastify, opts) {
throw new Error('"wildcard" option must be a boolean')
}
if (opts.wildcard === undefined || opts.wildcard === true) {
fastify.get(prefix + '*', { ...routeOpts, exposeHeadRoute: true }, (req, reply) => {
pumpSendToReply(req, reply, '/' + req.params['*'], sendOptions.root)
fastify.route({
...routeOpts,
method: ['HEAD', 'GET'],
path: prefix + '*',
handler (req, reply) {
pumpSendToReply(req, reply, '/' + req.params['*'], sendOptions.root)
}
})
if (opts.redirect === true && prefix !== opts.prefix) {
fastify.get(opts.prefix, routeOpts, (req, reply) => {
Expand Down Expand Up @@ -174,6 +179,7 @@ async function fastifyStatic (fastify, opts) {
pumpOptions,
checkedEncodings
) {
const pathnameOrig = pathname
const options = Object.assign({}, sendOptions, pumpOptions)

if (rootPath) {
Expand Down Expand Up @@ -215,7 +221,8 @@ async function fastifyStatic (fastify, opts) {
}
}

const stream = send(request.raw, pathnameForSend, options)
// `send(..., path, ...)` will URI-decode path so we pass an encoded path here
const stream = send(request.raw, encodeURI(pathnameForSend), options)
let resolvedFilename
stream.on('file', function (file) {
resolvedFilename = file
Expand Down Expand Up @@ -345,7 +352,7 @@ async function fastifyStatic (fastify, opts) {
return pumpSendToReply(
request,
reply,
pathname,
pathnameOrig,
rootPath,
rootPathOffset,
undefined,
Expand Down
2 changes: 1 addition & 1 deletion lib/dirList.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ const dirList = {
route = path.normalize(path.join(route, '..'))
}
return {
href: path.join(prefix, route, entry.name).replace(/\\/gu, '/'),
href: encodeURI(path.join(prefix, route, entry.name).replace(/\\/gu, '/')),
name: entry.name,
stats: entry.stats,
extendedInfo: entry.extendedInfo
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fastify/static",
"version": "7.0.1",
"version": "7.0.4",
"description": "Plugin for serving static files as fast as possible.",
"main": "index.js",
"type": "commonjs",
Expand Down Expand Up @@ -48,13 +48,13 @@
"coveralls": "^3.1.1",
"fastify": "^4.26.2",
"handlebars": "^4.7.8",
"pino": "^8.19.0",
"pino": "^9.1.0",
"proxyquire": "^2.1.3",
"simple-get": "^4.0.1",
"snazzy": "^9.0.0",
"standard": "^17.1.0",
"tap": "^18.7.1",
"tsd": "^0.30.7",
"tsd": "^0.31.0",
"typescript": "^5.4.3"
},
"tsd": {
Expand Down
14 changes: 8 additions & 6 deletions test/dir-list.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ t.test('dir list, custom options', t => {
}

const route = '/public/'
const content = { dirs: ['deep', 'shallow'], files: ['.example', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }
const content = { dirs: ['deep', 'shallow'], files: ['.example', '100%.txt', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }

helper.arrange(t, options, (url) => {
t.test(route, t => {
Expand Down Expand Up @@ -205,7 +205,8 @@ t.test('dir list html format', t => {
</ul>
<ul>
<li><a href="/public/.example" target="_blank">.example</a></li>
<li><a href="/public/a .md" target="_blank">a .md</a></li>
<li><a href="/public/100%25.txt" target="_blank">100%.txt</a></li>
<li><a href="/public/a%20.md" target="_blank">a .md</a></li>
<li><a href="/public/foo.html" target="_blank">foo.html</a></li>
<li><a href="/public/foobar.html" target="_blank">foobar.html</a></li>
<li><a href="/public/index.css" target="_blank">index.css</a></li>
Expand Down Expand Up @@ -236,7 +237,8 @@ t.test('dir list html format', t => {
</ul>
<ul>
<li><a href="/public/.example" target="_blank">.example</a></li>
<li><a href="/public/a .md" target="_blank">a .md</a></li>
<li><a href="/public/100%25.txt" target="_blank">100%.txt</a></li>
<li><a href="/public/a%20.md" target="_blank">a .md</a></li>
<li><a href="/public/foo.html" target="_blank">foo.html</a></li>
<li><a href="/public/foobar.html" target="_blank">foobar.html</a></li>
<li><a href="/public/index.css" target="_blank">index.css</a></li>
Expand Down Expand Up @@ -492,7 +494,7 @@ t.test('json format with url parameter format', t => {
}
}
const route = '/public/'
const jsonContent = { dirs: ['deep', 'shallow'], files: ['.example', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }
const jsonContent = { dirs: ['deep', 'shallow'], files: ['.example', '100%.txt', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }

helper.arrange(t, options, (url) => {
simple.concat({
Expand Down Expand Up @@ -539,7 +541,7 @@ t.test('json format with url parameter format and without render option', t => {
}
}
const route = '/public/'
const jsonContent = { dirs: ['deep', 'shallow'], files: ['.example', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }
const jsonContent = { dirs: ['deep', 'shallow'], files: ['.example', '100%.txt', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }

helper.arrange(t, options, (url) => {
simple.concat({
Expand Down Expand Up @@ -588,7 +590,7 @@ t.test('html format with url parameter format', t => {
}
}
const route = '/public/'
const jsonContent = { dirs: ['deep', 'shallow'], files: ['.example', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }
const jsonContent = { dirs: ['deep', 'shallow'], files: ['.example', '100%.txt', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }

helper.arrange(t, options, (url) => {
simple.concat({
Expand Down
5 changes: 5 additions & 0 deletions test/static-pre-compressed/dir-gz/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<html>
<body>
dir-gz index
</body>
</html>
Binary file added test/static-pre-compressed/dir-gz/index.html.gz
Binary file not shown.
103 changes: 98 additions & 5 deletions test/static.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ const indexBr = fs.readFileSync(
const dirIndexBr = fs.readFileSync(
'./test/static-pre-compressed/dir/index.html.br'
)
const dirIndexGz = fs.readFileSync(
'./test/static-pre-compressed/dir-gz/index.html.gz'
)
const uncompressedStatic = fs
.readFileSync('./test/static-pre-compressed/uncompressed.html')
.toString('utf8')
Expand Down Expand Up @@ -1737,7 +1740,7 @@ t.test('with fastify-compress', t => {
})
})
t.test('register /static/ with schemaHide true', t => {
t.plan(4)
t.plan(3)

const pluginOptions = {
root: path.join(__dirname, '/static'),
Expand Down Expand Up @@ -1777,7 +1780,7 @@ t.test('register /static/ with schemaHide true', t => {
})

t.test('register /static/ with schemaHide false', t => {
t.plan(4)
t.plan(3)

const pluginOptions = {
root: path.join(__dirname, '/static'),
Expand Down Expand Up @@ -1817,7 +1820,7 @@ t.test('register /static/ with schemaHide false', t => {
})

t.test('register /static/ without schemaHide', t => {
t.plan(4)
t.plan(3)

const pluginOptions = {
root: path.join(__dirname, '/static'),
Expand Down Expand Up @@ -2954,7 +2957,7 @@ t.test('inject support', async (t) => {
})

t.test('routes should use custom errorHandler premature stream close', t => {
t.plan(4)
t.plan(3)

const pluginOptions = {
root: path.join(__dirname, '/static'),
Expand Down Expand Up @@ -2989,7 +2992,7 @@ t.test('routes should use custom errorHandler premature stream close', t => {
})

t.test('routes should fallback to default errorHandler', t => {
t.plan(4)
t.plan(3)

const pluginOptions = {
root: path.join(__dirname, '/static'),
Expand Down Expand Up @@ -3496,6 +3499,35 @@ t.test(
}
)

t.test(
'will serve precompressed gzip index in subdir',
async (t) => {
const pluginOptions = {
root: path.join(__dirname, '/static-pre-compressed'),
preCompressed: true
}

const fastify = Fastify()

fastify.register(fastifyStatic, pluginOptions)
t.teardown(fastify.close.bind(fastify))

const response = await fastify.inject({
method: 'GET',
url: '/dir-gz',
headers: {
'accept-encoding': 'gzip, deflate, br'
}
})

genericResponseChecks(t, response)
t.equal(response.headers['content-encoding'], 'gzip')
t.equal(response.statusCode, 200)
t.same(response.rawPayload, dirIndexGz)
t.end()
}
)

t.test(
'will serve precompressed index with alternative index option',
async (t) => {
Expand Down Expand Up @@ -3930,3 +3962,64 @@ t.test(
t.same(response2.body, aContent)
}
)

t.test(
'serves files with % in the filename',
async (t) => {
t.plan(2)

const txtContent = fs.readFileSync(path.join(__dirname, 'static', '100%.txt'), 'utf-8')

const pluginOptions = {
root: url.pathToFileURL(path.join(__dirname, '/static')),
wildcard: false
}

const fastify = Fastify()

fastify.register(fastifyStatic, pluginOptions)
const response = await fastify.inject({
method: 'GET',
url: '100%25.txt',
headers: {
'accept-encoding': '*, *'
}
})
t.equal(response.statusCode, 200)
t.same(response.body, txtContent)
}
)

t.test('content-length in head route should not return zero when using wildcard', t => {
t.plan(6)

const pluginOptions = {
root: path.join(__dirname, '/static')
}
const fastify = Fastify()

fastify.register(fastifyStatic, pluginOptions)

t.teardown(fastify.close.bind(fastify))

fastify.listen({ port: 0 }, err => {
t.error(err)

fastify.server.unref()

const file = fs.readFileSync(path.join(__dirname, '/static/index.html'))
const contentLength = Buffer.byteLength(file).toString()

simple.concat({
method: 'HEAD',
url: 'http://localhost:' + fastify.server.address().port + '/index.html',
followRedirect: false
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 200)
t.equal(response.headers['content-type'], 'text/html; charset=UTF-8')
t.equal(response.headers['content-length'], contentLength)
t.equal(body.toString(), '')
})
})
})
1 change: 1 addition & 0 deletions test/static/100%.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
100%

0 comments on commit 691606c

Please sign in to comment.