Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add logLevel option #502

Merged
merged 11 commits into from
Feb 2, 2025
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ Default: `{}`
Constraints that will be added to registered routes. See Fastify's documentation for
[route constraints](https://fastify.dev/docs/latest/Reference/Routes/#constraints).

#### `logLevel`

Default: `info`

Set log level to registered routes.
Fdawgs marked this conversation as resolved.
Show resolved Hide resolved

#### `prefixAvoidTrailingSlash`

Default: `false`
Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ async function fastifyStatic (fastify, opts) {
schema: {
hide: opts.schemaHide !== undefined ? opts.schemaHide : true
},
logLevel: opts.logLevel,
errorHandler (error, request, reply) {
if (error?.code === 'ERR_STREAM_PREMATURE_CLOSE') {
reply.request.raw.destroy()
Expand Down
173 changes: 173 additions & 0 deletions test/static.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'use strict'

Check failure on line 1 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Test (20, ubuntu-latest)

/home/runner/work/fastify-static/fastify-static/test/static.test.js

[Error: test failed] { code: 'ERR_TEST_FAILURE', failureType: 'testCodeFailure', cause: 'test failed', exitCode: 7, signal: null }

Check failure on line 1 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Test (22, macos-latest)

/Users/runner/work/fastify-static/fastify-static/test/static.test.js

[Error: test failed] { code: 'ERR_TEST_FAILURE', failureType: 'testCodeFailure', cause: 'test failed', exitCode: 7, signal: null }

Check failure on line 1 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Test (22, ubuntu-latest)

/home/runner/work/fastify-static/fastify-static/test/static.test.js

[Error: test failed] { code: 'ERR_TEST_FAILURE', failureType: 'testCodeFailure', cause: 'test failed', exitCode: 7, signal: null }

/* eslint n/no-deprecated-api: "off" */

Expand Down Expand Up @@ -3493,7 +3493,7 @@
}
})

genericResponseChecks(t, response)

Check failure on line 3496 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

't' is not defined
t.equal(response.headers['content-encoding'], 'br')
t.equal(response.statusCode, 200)
t.same(response.rawPayload, dirIndexBr)
Expand Down Expand Up @@ -3525,7 +3525,7 @@
genericResponseChecks(t, response)
t.equal(response.headers['content-encoding'], 'gzip')
t.equal(response.statusCode, 200)
t.same(response.rawPayload, dirIndexGz)

Check failure on line 3528 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

'simple' is not defined
t.end()
}
)
Expand All @@ -3538,7 +3538,7 @@
prefix: '/static-pre-compressed/',
preCompressed: true,
index: ['all-three.html']
}

Check failure on line 3541 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

'simple' is not defined

const fastify = Fastify()

Expand All @@ -3551,7 +3551,7 @@
headers: {
'accept-encoding': 'gzip, deflate, br'
}
})

Check failure on line 3554 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

'simple' is not defined

genericResponseChecks(t, response)
t.equal(response.headers['content-encoding'], 'br')
Expand All @@ -3563,7 +3563,7 @@

t.test(
'will serve precompressed file without content-type charset',
async (t) => {

Check failure on line 3566 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

'simple' is not defined
const pluginOptions = {
root: path.join(__dirname, '/static-pre-compressed'),
prefix: '/static-pre-compressed/',
Expand All @@ -3576,7 +3576,7 @@
t.teardown(fastify.close.bind(fastify))

const response = await fastify.inject({
method: 'GET',

Check failure on line 3579 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

'simple' is not defined
url: '/static-pre-compressed/sample.jpg',
headers: {
'accept-encoding': 'gzip, deflate, br'
Expand All @@ -3589,7 +3589,7 @@
t.end()
}
)

Check failure on line 3592 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

'simple' is not defined
t.test(
'nonexistent index with precompressed option',
async (t) => {
Expand All @@ -3602,7 +3602,7 @@
const fastify = Fastify()

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

Check failure on line 3605 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

'simple' is not defined

const response = await fastify.inject({
method: 'GET',
Expand All @@ -3615,7 +3615,7 @@
t.equal(response.statusCode, 404)
genericErrorResponseChecks(t, response)
t.end()
}

Check failure on line 3618 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

'simple' is not defined
)

t.test('should not redirect to protocol-relative locations', (t) => {
Expand All @@ -3628,7 +3628,7 @@
['/^', null, 404], // it is NOT recognized as a directory by pillarjs/send
['//google.com/%2e%2e', '/', 301],
['//users/%2e%2e', '/', 301],
['//users', null, 404],

Check failure on line 3631 in test/static.test.js

View workflow job for this annotation

GitHub Actions / test / Lint Code

'simple' is not defined
['///deep/path//for//test//index.html', null, 200]
]

Expand Down Expand Up @@ -4102,3 +4102,176 @@
})
})
})

t.test('register /static/ with custom log level', t => {
t.plan(11)

const pluginOptions = {
root: path.join(__dirname, '/static'),
prefix: '/static/',
logLevel: 'warn'
}
const fastify = Fastify({
logger: {
stream: {
write: (logLine) => {
const log = JSON.parse(logLine)

if (log.reqId) {
t.fail('Not expecting any log since plugin\'s log level is set at WARN')
}
},
},
},
})
fastify.register(fastifyStatic, pluginOptions)

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

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

fastify.server.unref()

t.test('/static/index.html', (t) => {
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/index.html'
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 200)
t.equal(body.toString(), indexContent)
genericResponseChecks(t, response)
})
})

t.test('/static/index.html', t => {
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'HEAD',
url: 'http://localhost:' + fastify.server.address().port + '/static/index.html'
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 200)
t.equal(body.toString(), '')
genericResponseChecks(t, response)
})
})

t.test('/static/index.css', (t) => {
t.plan(2 + GENERIC_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/index.css'
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 200)
genericResponseChecks(t, response)
})
})

t.test('/static/', (t) => {
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/'
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 200)
t.equal(body.toString(), indexContent)
genericResponseChecks(t, response)
})
})

t.test('/static/deep/path/for/test/purpose/foo.html', (t) => {
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/deep/path/for/test/purpose/foo.html'
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 200)
t.equal(body.toString(), deepContent)
genericResponseChecks(t, response)
})
})

t.test('/static/deep/path/for/test/', (t) => {
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/deep/path/for/test/'
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 200)
t.equal(body.toString(), innerIndex)
genericResponseChecks(t, response)
})
})

t.test('/static/this/path/for/test', (t) => {
t.plan(2 + GENERIC_ERROR_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/this/path/for/test',
followRedirect: false
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 404)
genericErrorResponseChecks(t, response)
})
})

t.test('/static/this/path/doesnt/exist.html', (t) => {
t.plan(2 + GENERIC_ERROR_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/this/path/doesnt/exist.html',
followRedirect: false
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 404)
genericErrorResponseChecks(t, response)
})
})

t.test('/static/../index.js', (t) => {
t.plan(2 + GENERIC_ERROR_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/../index.js',
followRedirect: false
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 403)
genericErrorResponseChecks(t, response)
})
})

t.test('304', t => {
t.plan(5 + GENERIC_RESPONSE_CHECK_COUNT)
simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/index.html'
}, (err, response, body) => {
t.error(err)
const etag = response.headers.etag
t.equal(response.statusCode, 200)
t.equal(body.toString(), indexContent)
genericResponseChecks(t, response)

simple.concat({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port + '/static/index.html',
headers: {
'if-none-match': etag
}
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 304)
})
})
})
})
})
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ declare namespace fastifyStatic {
lastModified?: boolean;
maxAge?: string | number;
constraints?: RouteOptions['constraints'];
logLevel?: RouteOptions['logLevel'];
}

export const fastifyStatic: FastifyStaticPlugin
Expand Down
3 changes: 2 additions & 1 deletion types/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ const options: FastifyStaticOptions = {
constraints: {
host: /.*\.example\.com/,
version: '1.0.2'
}
},
logLevel: 'warn'
}

expectError<FastifyStaticOptions>({
Expand Down
Loading