Socket
Socket
Sign inDemoInstall

fastify

Package Overview
Dependencies
Maintainers
3
Versions
288
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fastify - npm Package Compare versions

Comparing version 3.28.0 to 3.29.4

78

docs/Guides/Ecosystem.md

@@ -11,9 +11,9 @@ <h1 align="center">Fastify</h1>

- [`fastify-accepts`](https://github.com/fastify/fastify-accepts) to have
- [`@fastify/accepts`](https://github.com/fastify/fastify-accepts) to have
[accepts](https://www.npmjs.com/package/accepts) in your request object.
- [`fastify-accepts-serializer`](https://github.com/fastify/fastify-accepts-serializer)
- [`@fastify/accepts-serializer`](https://github.com/fastify/fastify-accepts-serializer)
to serialize to output according to `Accept` header.
- [`fastify-auth`](https://github.com/fastify/fastify-auth) Run multiple auth
- [`@fastify/auth`](https://github.com/fastify/fastify-auth) Run multiple auth
functions in Fastify.
- [`fastify-autoload`](https://github.com/fastify/fastify-autoload) Require all
- [`@fastify/autoload`](https://github.com/fastify/fastify-autoload) Require all
plugins in a directory.

@@ -23,17 +23,17 @@ - [`fastify-awilix`](https://github.com/fastify/fastify-awilix) Dependency

[awilix](https://github.com/jeffijoe/awilix).
- [`fastify-bankai`](https://github.com/fastify/fastify-bankai)
- [`@fastify/bankai`](https://github.com/fastify/fastify-bankai)
[Bankai](https://github.com/yoshuawuyts/bankai) assets compiler for Fastify.
- [`fastify-basic-auth`](https://github.com/fastify/fastify-basic-auth) Basic
- [`@fastify/basic-auth`](https://github.com/fastify/fastify-basic-auth) Basic
auth plugin for Fastify.
- [`fastify-bearer-auth`](https://github.com/fastify/fastify-bearer-auth) Bearer
- [`@fastify/bearer-auth`](https://github.com/fastify/fastify-bearer-auth) Bearer
auth plugin for Fastify.
- [`fastify-caching`](https://github.com/fastify/fastify-caching) General
- [`@fastify/caching`](https://github.com/fastify/fastify-caching) General
server-side cache and ETag support.
- [`fastify-circuit-breaker`](https://github.com/fastify/fastify-circuit-breaker)
- [`@fastify/circuit-breaker`](https://github.com/fastify/fastify-circuit-breaker)
A low overhead circuit breaker for your routes.
- [`fastify-compress`](https://github.com/fastify/fastify-compress) Fastify
- [`@fastify/compress`](https://github.com/fastify/fastify-compress) Fastify
compression utils.
- [`fastify-cookie`](https://github.com/fastify/fastify-cookie) Parse and set
- [`@fastify/cookie`](https://github.com/fastify/fastify-cookie) Parse and set
cookie headers.
- [`fastify-cors`](https://github.com/fastify/fastify-cors) Enables the use of
- [`@fastify/cors`](https://github.com/fastify/fastify-cors) Enables the use of
CORS in a Fastify application.

@@ -43,39 +43,39 @@ - [`fastify-csrf`](https://github.com/fastify/fastify-csrf) A plugin for adding

Fastify.
- [`fastify-diagnostics-channel`](https://github.com/fastify/fastify-diagnostics-channel)
- [`@fastify/diagnostics-channel`](https://github.com/fastify/fastify-diagnostics-channel)
Plugin to deal with `diagnostics_channel` on Fastify
- [`fastify-elasticsearch`](https://github.com/fastify/fastify-elasticsearch)
- [`@fastify/elasticsearch`](https://github.com/fastify/fastify-elasticsearch)
Plugin to share the same ES client.
- [`fastify-env`](https://github.com/fastify/fastify-env) Load and check
- [`@fastify/env`](https://github.com/fastify/fastify-env) Load and check
configuration.
- [`fastify-etag`](https://github.com/fastify/fastify-etag) Automatically
- [`@fastify/etag`](https://github.com/fastify/fastify-etag) Automatically
generate ETags for HTTP responses.
- [`fastify-flash`](https://github.com/fastify/fastify-flash) Set and get flash
- [`@fastify/flash`](https://github.com/fastify/fastify-flash) Set and get flash
messages using the session.
- [`fastify-formbody`](https://github.com/fastify/fastify-formbody) Plugin to
- [`@fastify/formbody`](https://github.com/fastify/fastify-formbody) Plugin to
parse x-www-form-urlencoded bodies.
- [`fastify-funky`](https://github.com/fastify/fastify-funky) Makes functional
- [`@fastify/funky`](https://github.com/fastify/fastify-funky) Makes functional
programming in Fastify more convenient. Adds support for Fastify routes
returning functional structures, such as Either, Task or plain parameterless
function.
- [`fastify-helmet`](https://github.com/fastify/fastify-helmet) Important
- [`@fastify/helmet`](https://github.com/fastify/fastify-helmet) Important
security headers for Fastify.
- [`fastify-http-proxy`](https://github.com/fastify/fastify-http-proxy) Proxy
- [`@fastify/http-proxy`](https://github.com/fastify/fastify-http-proxy) Proxy
your HTTP requests to another server, with hooks.
- [`fastify-jwt`](https://github.com/fastify/fastify-jwt) JWT utils for Fastify,
- [`@fastify/jwt`](https://github.com/fastify/fastify-jwt) JWT utils for Fastify,
internally uses [fast-jwt](https://github.com/nearform/fast-jwt).
- [`fastify-leveldb`](https://github.com/fastify/fastify-leveldb) Plugin to
- [`@fastify/leveldb`](https://github.com/fastify/fastify-leveldb) Plugin to
share a common LevelDB connection across Fastify.
- [`fastify-mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
- [`@fastify/mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
MongoDB connection plugin, with which you can share the same MongoDB
connection pool across every part of your server.
- [`fastify-multipart`](https://github.com/fastify/fastify-multipart) Multipart
- [`@fastify/multipart`](https://github.com/fastify/fastify-multipart) Multipart
support for Fastify.
- [`fastify-oauth2`](https://github.com/fastify/fastify-oauth2) Wrap around
- [`@fastify/oauth2`](https://github.com/fastify/fastify-oauth2) Wrap around
[`simple-oauth2`](https://github.com/lelylan/simple-oauth2).
- [`fastify-postgres`](https://github.com/fastify/fastify-postgres) Fastify
- [`@fastify/postgres`](https://github.com/fastify/fastify-postgres) Fastify
PostgreSQL connection plugin, with this you can share the same PostgreSQL
connection pool in every part of your server.
- [`fastify-rate-limit`](https://github.com/fastify/fastify-rate-limit) A low
- [`@fastify/rate-limit`](https://github.com/fastify/fastify-rate-limit) A low
overhead rate limiter for your routes.
- [`fastify-request-context`](https://github.com/fastify/fastify-request-context)
- [`@fastify/request-context`](https://github.com/fastify/fastify-request-context)
Request-scoped storage, based on

@@ -85,13 +85,13 @@ [AsyncLocalStorage](https://nodejs.org/api/async_hooks.html#async_hooks_class_asynclocalstorage)

providing functionality similar to thread-local storages.
- [`fastify-response-validation`](https://github.com/fastify/fastify-response-validation)
- [`@fastify/response-validation`](https://github.com/fastify/fastify-response-validation)
A simple plugin that enables response validation for Fastify.
- [`fastify-nextjs`](https://github.com/fastify/fastify-nextjs) React
- [`@fastify/nextjs`](https://github.com/fastify/fastify-nextjs) React
server-side rendering support for Fastify with
[Next](https://github.com/zeit/next.js/).
- [`fastify-redis`](https://github.com/fastify/fastify-redis) Fastify Redis
- [`@fastify/redis`](https://github.com/fastify/fastify-redis) Fastify Redis
connection plugin, with which you can share the same Redis connection across
every part of your server.
- [`fastify-reply-from`](https://github.com/fastify/fastify-reply-from) Plugin
- [`@fastify/reply-from`](https://github.com/fastify/fastify-reply-from) Plugin
to forward the current HTTP request to another server.
- [`fastify-routes`](https://github.com/fastify/fastify-routes) Plugin that
- [`@fastify/routes`](https://github.com/fastify/fastify-routes) Plugin that
provides a `Map` of routes.

@@ -101,3 +101,3 @@ - [`fastify-schedule`](https://github.com/fastify/fastify-schedule) Plugin for

[toad-scheduler](https://github.com/kibertoad/toad-scheduler).
- [`fastify-sensible`](https://github.com/fastify/fastify-sensible) Defaults for
- [`@fastify/sensible`](https://github.com/fastify/fastify-sensible) Defaults for
Fastify that everyone can agree on. It adds some useful decorators such as

@@ -107,10 +107,10 @@ HTTP errors and assertions, but also more request and reply methods.

Fastify.
- [`fastify-static`](https://github.com/fastify/fastify-static) Plugin for
- [`@fastify/static`](https://github.com/fastify/fastify-static) Plugin for
serving static files as fast as possible.
- [`fastify-swagger`](https://github.com/fastify/fastify-swagger) Plugin for
- [`@fastify/swagger`](https://github.com/fastify/fastify-swagger) Plugin for
serving Swagger/OpenAPI documentation for Fastify, supporting dynamic
generation.
- [`fastify-websocket`](https://github.com/fastify/fastify-websocket) WebSocket
- [`@fastify/websocket`](https://github.com/fastify/fastify-websocket) WebSocket
support for Fastify. Built upon [ws](https://github.com/websockets/ws).
- [`fastify-url-data`](https://github.com/fastify/fastify-url-data) Decorate the
- [`@fastify/url-data`](https://github.com/fastify/fastify-url-data) Decorate the
`Request` object with a method to access raw URL components.

@@ -117,0 +117,0 @@ - [`middie`](https://github.com/fastify/middie) Middleware engine for Fastify.

@@ -198,6 +198,6 @@ <h1 align="center">Fastify</h1>

First, install `fastify-plugin` and `fastify-mongodb`:
First, install `fastify-plugin` and `@fastify/mongodb`:
```
npm i --save fastify-plugin fastify-mongodb
npm i --save fastify-plugin @fastify/mongodb
```

@@ -250,3 +250,3 @@

import fastifyPlugin from 'fastify-plugin'
import fastifyMongo from 'fastify-mongodb'
import fastifyMongo from '@fastify/mongodb'

@@ -270,3 +270,3 @@ async function dbConnector (fastify, options) {

async function dbConnector (fastify, options) {
fastify.register(require('fastify-mongodb'), {
fastify.register(require('@fastify/mongodb'), {
url: 'mongodb://localhost:27017/test_database'

@@ -273,0 +273,0 @@ })

@@ -17,3 +17,3 @@ # V3 Migration Guide

If you use Express middleware in your application, please install and register
the [`fastify-express`](https://github.com/fastify/fastify-express) or
the [`@fastify/express`](https://github.com/fastify/fastify-express) or
[`middie`](https://github.com/fastify/middie) plugin before doing so.

@@ -32,3 +32,3 @@

// Using the Express `cors` middleware in Fastify v3.
await fastify.register(require('fastify-express'));
await fastify.register(require('@fastify/express'));
fastify.use(require('cors')());

@@ -35,0 +35,0 @@ ```

@@ -448,6 +448,6 @@ <h1 align="center">Fastify</h1>

error objects across your codebase and plugins with the
[`fastify-error`](https://github.com/fastify/fastify-error) module.
[`@fastify/error`](https://github.com/fastify/fastify-error) module.
```js
const createError = require('fastify-error')
const createError = require('@fastify/error')
const CustomError = createError('ERROR_CODE', 'message')

@@ -481,8 +481,8 @@ console.log(new CustomError())

rendering (*ejs, pug, handlebars, marko*) plugin support for Fastify.
- [`fastify-mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
- [`@fastify/mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
MongoDB connection plugin, with this you can share the same MongoDB connection
pool in every part of your server.
- [`fastify-multipart`](https://github.com/fastify/fastify-multipart) Multipart
- [`@fastify/multipart`](https://github.com/fastify/fastify-multipart) Multipart
support for Fastify
- [`fastify-helmet`](https://github.com/fastify/fastify-helmet) Important
- [`@fastify/helmet`](https://github.com/fastify/fastify-helmet) Important
security headers for Fastify

@@ -489,0 +489,0 @@

@@ -36,5 +36,5 @@ <h1 align="center">Fastify</h1>

at:
- [`fastify-caching`](https://github.com/fastify/fastify-caching)
- [`fastify-compress`](https://github.com/fastify/fastify-compress)
- [`fastify-cookie`](https://github.com/fastify/fastify-cookie)
- [`@fastify/caching`](https://github.com/fastify/fastify-caching)
- [`@fastify/compress`](https://github.com/fastify/fastify-compress)
- [`@fastify/cookie`](https://github.com/fastify/fastify-cookie)
- [`point-of-view`](https://github.com/fastify/point-of-view)

@@ -97,8 +97,8 @@ - [`under-pressure`](https://github.com/fastify/under-pressure)

rendering (*ejs, pug, handlebars, marko*) plugin support for Fastify.
- [`fastify-mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
- [`@fastify/mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
MongoDB connection plugin, with this you can share the same MongoDB connection
pool in every part of your server.
- [`fastify-multipart`](https://github.com/fastify/fastify-multipart) Multipart
- [`@fastify/multipart`](https://github.com/fastify/fastify-multipart) Multipart
support for Fastify.
- [`fastify-helmet`](https://github.com/fastify/fastify-helmet) Important
- [`@fastify/helmet`](https://github.com/fastify/fastify-helmet) Important
security headers for Fastify.

@@ -36,3 +36,3 @@ <h1 align="center">Fastify</h1>

access to the same context as the second route. Using
[fastify-bearer-auth][bearer] to provide the authentication, the code for this
[@fastify/bearer-auth][bearer] to provide the authentication, the code for this
example is as follows:

@@ -48,3 +48,3 @@

fastify.register(async function authenticatedContext (childServer) {
childServer.register(require('fastify-bearer-auth'), { keys: ['abc123'] })
childServer.register(require('@fastify/bearer-auth'), { keys: ['abc123'] })

@@ -108,3 +108,3 @@ childServer.route({

the _root context_.
2. Only the `authenticatedContext` has access to the `fastify-bearer-auth`
2. Only the `authenticatedContext` has access to the `@fastify/bearer-auth`
plugin.

@@ -111,0 +111,0 @@ 3. Both the `publicContext` and `grandchildContext` have access to the `foo`

@@ -354,3 +354,3 @@ <h1 align="center">Fastify</h1>

fastify.addHook('preHandler', async (request, reply) => {
// the fastify-static plugin will send a file asynchronously,
// the @fastify/static plugin will send a file asynchronously,
// so we should return reply

@@ -357,0 +357,0 @@ reply.sendFile('myfile')

@@ -7,3 +7,3 @@ <h1 align="center">Fastify</h1>

requires an external plugin such as
[`fastify-express`](https://github.com/fastify/fastify-express) or
[`@fastify/express`](https://github.com/fastify/fastify-express) or
[`middie`](https://github.com/fastify/middie).

@@ -13,7 +13,7 @@

An example of registering the
[`fastify-express`](https://github.com/fastify/fastify-express) plugin to `use`
[`@fastify/express`](https://github.com/fastify/fastify-express) plugin to `use`
Express middleware:
```js
await fastify.register(require('fastify-express'))
await fastify.register(require('@fastify/express'))
fastify.use(require('cors')())

@@ -75,7 +75,7 @@ fastify.use(require('dns-prefetch-control')())

Fastify offers some alternatives to the most commonly used middleware, such as
[`fastify-helmet`](https://github.com/fastify/fastify-helmet) in case of
[`@fastify/helmet`](https://github.com/fastify/fastify-helmet) in case of
[`helmet`](https://github.com/helmetjs/helmet),
[`fastify-cors`](https://github.com/fastify/fastify-cors) for
[`@fastify/cors`](https://github.com/fastify/fastify-cors) for
[`cors`](https://github.com/expressjs/cors), and
[`fastify-static`](https://github.com/fastify/fastify-static) for
[`@fastify/static`](https://github.com/fastify/fastify-static) for
[`serve-static`](https://github.com/expressjs/serve-static).

@@ -486,3 +486,3 @@ <h1 align="center">Fastify</h1>

[`http-errors`](https://npm.im/http-errors) module or
[`fastify-sensible`](https://github.com/fastify/fastify-sensible) plugin to
[`@fastify/sensible`](https://github.com/fastify/fastify-sensible) plugin to
generate errors:

@@ -489,0 +489,0 @@

@@ -607,3 +607,3 @@ <h1 align="center">Fastify</h1>

out
[fastify-swagger](https://github.com/fastify/fastify-swagger/blob/master/index.d.ts).
[@fastify/swagger](https://github.com/fastify/fastify-swagger/blob/master/index.d.ts).

@@ -610,0 +610,0 @@ With those files completed, the plugin is now ready to be consumed by any

@@ -12,3 +12,3 @@ import * as http from 'http'

import { Options as AjvOptions } from '@fastify/ajv-compiler'
import { FastifyError } from 'fastify-error'
import { FastifyError } from '@fastify/error'
import { FastifyReply } from './types/reply'

@@ -167,3 +167,3 @@ import { FastifySchemaValidationError } from './types/schema'

declare module 'fastify-error' {
declare module '@fastify/error' {
interface FastifyError {

@@ -193,3 +193,3 @@ validation?: ValidationResult[];

export { FastifyBodyParser, FastifyContentTypeParser, AddContentTypeParser, hasContentTypeParser, getDefaultJsonParser, ProtoAction, ConstructorAction } from './types/content-type-parser'
export { FastifyError } from 'fastify-error'
export { FastifyError } from '@fastify/error'
export { FastifySchema, FastifySchemaCompiler } from './types/schema'

@@ -196,0 +196,0 @@ export { HTTPMethods, RawServerBase, RawRequestDefaultExpression, RawReplyDefaultExpression, RawServerDefault, ContextConfigDefault, RequestBodyDefault, RequestQuerystringDefault, RequestParamsDefault, RequestHeadersDefault } from './types/utils'

'use strict'
const VERSION = '3.28.0'
const VERSION = '3.29.4'

@@ -587,3 +587,3 @@ const Avvio = require('avvio')

// If the socket is not writable, there is no reason to try to send data.
if (socket.writable && socket.bytesWritten === 0) {
if (socket.writable) {
socket.write(`HTTP/1.1 400 Bad Request\r\nContent-Length: ${body.length}\r\nContent-Type: application/json\r\n\r\n${body}`)

@@ -590,0 +590,0 @@ }

@@ -9,2 +9,3 @@ 'use strict'

lru = typeof lru === 'function' ? lru : lru.default
const { parse: parseContentType } = require('content-type')

@@ -36,6 +37,7 @@ const secureJson = require('secure-json-parse')

this[kDefaultJsonParse] = getDefaultJsonParser(onProtoPoisoning, onConstructorPoisoning)
this.customParsers = {}
this.customParsers['application/json'] = new Parser(true, false, bodyLimit, this[kDefaultJsonParse])
this.customParsers['text/plain'] = new Parser(true, false, bodyLimit, defaultPlainTextParser)
this.parserList = ['application/json', 'text/plain']
// using a map instead of a plain object to avoid prototype hijack attacks
this.customParsers = new Map()
this.customParsers.set('application/json', new Parser(true, false, bodyLimit, this[kDefaultJsonParse]))
this.customParsers.set('text/plain', new Parser(true, false, bodyLimit, defaultPlainTextParser))
this.parserList = [new ParserListItem('application/json'), new ParserListItem('text/plain')]
this.parserRegExpList = []

@@ -70,10 +72,10 @@ this.cache = lru(100)

if (contentTypeIsString && contentType === '*') {
this.customParsers[''] = parser
this.customParsers.set('', parser)
} else {
if (contentTypeIsString) {
this.parserList.unshift(contentType)
this.parserList.unshift(new ParserListItem(contentType))
} else {
this.parserRegExpList.unshift(contentType)
}
this.customParsers[contentType] = parser
this.customParsers.set(contentType.toString(), parser)
}

@@ -83,22 +85,40 @@ }

ContentTypeParser.prototype.hasParser = function (contentType) {
return contentType in this.customParsers
return this.customParsers.has(typeof contentType === 'string' ? contentType : contentType.toString())
}
ContentTypeParser.prototype.existingParser = function (contentType) {
if (contentType === 'application/json') {
return this.customParsers['application/json'] && this.customParsers['application/json'].fn !== this[kDefaultJsonParse]
if (contentType === 'application/json' && this.customParsers.has(contentType)) {
return this.customParsers.get(contentType).fn !== this[kDefaultJsonParse]
}
if (contentType === 'text/plain') {
return this.customParsers['text/plain'] && this.customParsers['text/plain'].fn !== defaultPlainTextParser
if (contentType === 'text/plain' && this.customParsers.has(contentType)) {
return this.customParsers.get(contentType).fn !== defaultPlainTextParser
}
return contentType in this.customParsers
return this.hasParser(contentType)
}
ContentTypeParser.prototype.getParser = function (contentType) {
if (this.hasParser(contentType)) {
return this.customParsers.get(contentType)
}
const parser = this.cache.get(contentType)
// TODO not covered by tests, this is a security backport
/* istanbul ignore next */
if (parser !== undefined) return parser
const parsed = safeParseContentType(contentType)
// dummyContentType always the same object
// we can use === for the comparsion and return early
if (parsed === dummyContentType) {
return this.customParsers.get('')
}
// eslint-disable-next-line no-var
for (var i = 0; i !== this.parserList.length; ++i) {
const parserName = this.parserList[i]
if (contentType.indexOf(parserName) > -1) {
const parser = this.customParsers[parserName]
const parserListItem = this.parserList[i]
if (compareContentType(parsed, parserListItem)) {
const parser = this.customParsers.get(parserListItem.name)
// we set request content-type in cache to reduce parsing of MIME type
this.cache.set(contentType, parser)

@@ -112,4 +132,5 @@ return parser

const parserRegExp = this.parserRegExpList[j]
if (parserRegExp.test(contentType)) {
const parser = this.customParsers[parserRegExp]
if (compareRegExpContentType(contentType, parsed.type, parserRegExp)) {
const parser = this.customParsers.get(parserRegExp.toString())
// we set request content-type in cache to reduce parsing of MIME type
this.cache.set(contentType, parser)

@@ -120,7 +141,7 @@ return parser

return this.customParsers['']
return this.customParsers.get('')
}
ContentTypeParser.prototype.removeAll = function () {
this.customParsers = {}
this.customParsers = new Map()
this.parserRegExpList = []

@@ -134,3 +155,3 @@ this.parserList = []

delete this.customParsers[contentType]
this.customParsers.delete(contentType.toString())

@@ -300,3 +321,3 @@ const parsers = typeof contentType === 'string' ? this.parserList : this.parserRegExpList

contentTypeParser[kDefaultJsonParse] = c[kDefaultJsonParse]
Object.assign(contentTypeParser.customParsers, c.customParsers)
contentTypeParser.customParsers = new Map(c.customParsers.entries())
contentTypeParser.parserList = c.parserList.slice()

@@ -354,2 +375,59 @@ return contentTypeParser

// dummy here to prevent repeated object creation
const dummyContentType = { type: '', parameters: Object.create(null) }
function safeParseContentType (contentType) {
try {
return parseContentType(contentType)
} catch (err) {
return dummyContentType
}
}
function compareContentType (contentType, parserListItem) {
if (parserListItem.isEssence) {
// we do essence check
return contentType.type.indexOf(parserListItem) !== -1
} else {
// when the content-type includes parameters
// we do a full-text search
// reject essence content-type before checking parameters
if (contentType.type.indexOf(parserListItem.type) === -1) return false
for (const key of parserListItem.parameterKeys) {
// reject when missing parameters
if (!(key in contentType.parameters)) return false
// reject when parameters do not match
if (contentType.parameters[key] !== parserListItem.parameters[key]) return false
}
return true
}
}
function compareRegExpContentType (contentType, essenceMIMEType, regexp) {
if (regexp.source.indexOf(';') === -1) {
// we do essence check
return regexp.test(essenceMIMEType)
} else {
// when the content-type includes parameters
// we do a full-text match
return regexp.test(contentType)
}
}
function ParserListItem (contentType) {
this.name = contentType
// we pre-calculate all the needed information
// before content-type comparsion
const parsed = safeParseContentType(contentType)
this.type = parsed.type
this.parameters = parsed.parameters
this.parameterKeys = Object.keys(parsed.parameters)
this.isEssence = contentType.indexOf(';') === -1
}
// used in ContentTypeParser.remove
ParserListItem.prototype.toString = function () {
return this.name
}
module.exports = ContentTypeParser

@@ -356,0 +434,0 @@ module.exports.helpers = {

'use strict'
const createError = require('fastify-error')
const createError = require('@fastify/error')
const codes = {

@@ -5,0 +5,0 @@ /**

@@ -548,3 +548,3 @@ 'use strict'

if (err != null) {
if (res.headersSent) {
if (res.headersSent || reply.request.raw.aborted === true) {
if (!errorLogged) {

@@ -551,0 +551,0 @@ errorLogged = true

{
"name": "fastify",
"version": "3.28.0",
"version": "3.29.4",
"description": "Fast and low overhead web framework, for Node.js",

@@ -130,5 +130,4 @@ "main": "fastify.js",

"@types/pino": "^6.0.1",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"JSONStream": "^1.3.5",
"@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0",
"ajv": "^6.0.0",

@@ -144,7 +143,7 @@ "ajv-errors": "^1.0.1",

"dns-prefetch-control": "^0.3.0",
"eslint": "^8.0.1",
"eslint": "^8.14.0",
"eslint-config-standard": "^17.0.0-1",
"eslint-import-resolver-node": "^0.3.2",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-n": "^14.0.0",
"eslint-import-resolver-node": "^0.3.6",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.2.0",
"eslint-plugin-promise": "^6.0.0",

@@ -162,2 +161,3 @@ "fast-json-body": "^1.1.0",

"ienoopen": "^1.1.0",
"JSONStream": "^1.3.5",
"license-checker": "^25.0.1",

@@ -172,3 +172,3 @@ "pem": "^1.14.4",

"split2": "^4.1.0",
"standard": "^17.0.0-2",
"standard": "^17.0.0",
"tap": "^15.1.1",

@@ -185,7 +185,6 @@ "tap-mocha-reporter": "^5.0.1",

"@fastify/ajv-compiler": "^1.0.0",
"@fastify/error": "^2.0.0",
"abstract-logging": "^2.0.0",
"avvio": "^7.1.2",
"fast-json-stringify": "^2.5.2",
"fastify-error": "^0.3.0",
"process-warning": "^1.0.0",
"find-my-way": "^4.5.0",

@@ -195,2 +194,4 @@ "flatstr": "^1.0.12",

"pino": "^6.13.0",
"process-warning": "^1.0.0",
"content-type": "^1.0.4",
"proxy-addr": "^2.0.7",

@@ -197,0 +198,0 @@ "rfdc": "^1.1.4",

@@ -184,3 +184,3 @@ 'use strict'

contentTypeParser.add('*', {}, first)
t.equal(contentTypeParser.customParsers[''].fn, first)
t.equal(contentTypeParser.customParsers.get('').fn, first)
})

@@ -243,3 +243,3 @@

t.same(Object.keys(contentTypeParser.customParsers).length, 2)
t.same(contentTypeParser.customParsers.size, 2)
})

@@ -267,1 +267,281 @@

})
test('Safeguard against malicious content-type / 1', async t => {
const badNames = Object.getOwnPropertyNames({}.__proto__) // eslint-disable-line
t.plan(badNames.length)
const fastify = Fastify()
fastify.post('/', async () => {
return 'ok'
})
for (const prop of badNames) {
const response = await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': prop
},
body: ''
})
t.same(response.statusCode, 415)
}
})
test('Safeguard against malicious content-type / 2', async t => {
t.plan(1)
const fastify = Fastify()
fastify.post('/', async () => {
return 'ok'
})
const response = await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': '\\u0063\\u006fnstructor'
},
body: ''
})
t.same(response.statusCode, 415)
})
test('Safeguard against malicious content-type / 3', async t => {
t.plan(1)
const fastify = Fastify()
fastify.post('/', async () => {
return 'ok'
})
const response = await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': 'constructor; charset=utf-8'
},
body: ''
})
t.same(response.statusCode, 415)
})
test('Safeguard against content-type spoofing - string', async t => {
t.plan(1)
const fastify = Fastify()
fastify.removeAllContentTypeParsers()
fastify.addContentTypeParser('text/plain', function (request, body, done) {
t.pass('should be called')
done(null, body)
})
fastify.addContentTypeParser('application/json', function (request, body, done) {
t.fail('shouldn\'t be called')
done(null, body)
})
fastify.post('/', async () => {
return 'ok'
})
await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': 'text/plain; content-type="application/json"'
},
body: ''
})
})
test('Safeguard against content-type spoofing - regexp', async t => {
t.plan(1)
const fastify = Fastify()
fastify.removeAllContentTypeParsers()
fastify.addContentTypeParser(/text\/plain/, function (request, body, done) {
t.pass('should be called')
done(null, body)
})
fastify.addContentTypeParser(/application\/json/, function (request, body, done) {
t.fail('shouldn\'t be called')
done(null, body)
})
fastify.post('/', async () => {
return 'ok'
})
await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': 'text/plain; content-type="application/json"'
},
body: ''
})
})
test('content-type match parameters - string 1', async t => {
t.plan(1)
const fastify = Fastify()
fastify.removeAllContentTypeParsers()
fastify.addContentTypeParser('text/plain; charset=utf8', function (request, body, done) {
t.fail('shouldn\'t be called')
done(null, body)
})
fastify.addContentTypeParser('application/json; charset=utf8', function (request, body, done) {
t.pass('should be called')
done(null, body)
})
fastify.post('/', async () => {
return 'ok'
})
await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': 'application/json; charset=utf8'
},
body: ''
})
})
test('content-type match parameters - string 2', async t => {
t.plan(1)
const fastify = Fastify()
fastify.removeAllContentTypeParsers()
fastify.addContentTypeParser('application/json; charset=utf8; foo=bar', function (request, body, done) {
t.pass('should be called')
done(null, body)
})
fastify.addContentTypeParser('text/plain; charset=utf8; foo=bar', function (request, body, done) {
t.fail('shouldn\'t be called')
done(null, body)
})
fastify.post('/', async () => {
return 'ok'
})
await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': 'application/json; foo=bar; charset=utf8'
},
body: ''
})
})
test('content-type match parameters - regexp', async t => {
t.plan(1)
const fastify = Fastify()
fastify.removeAllContentTypeParsers()
fastify.addContentTypeParser(/application\/json; charset=utf8/, function (request, body, done) {
t.pass('should be called')
done(null, body)
})
fastify.post('/', async () => {
return 'ok'
})
await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': 'application/json; charset=utf8'
},
body: ''
})
})
test('content-type fail when parameters not match - string 1', async t => {
t.plan(1)
const fastify = Fastify()
fastify.removeAllContentTypeParsers()
fastify.addContentTypeParser('application/json; charset=utf8; foo=bar', function (request, body, done) {
t.fail('shouldn\'t be called')
done(null, body)
})
fastify.post('/', async () => {
return 'ok'
})
const response = await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': 'application/json; charset=utf8'
},
body: ''
})
t.same(response.statusCode, 415)
})
test('content-type fail when parameters not match - string 2', async t => {
t.plan(1)
const fastify = Fastify()
fastify.removeAllContentTypeParsers()
fastify.addContentTypeParser('application/json; charset=utf8; foo=bar', function (request, body, done) {
t.fail('shouldn\'t be called')
done(null, body)
})
fastify.post('/', async () => {
return 'ok'
})
const response = await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': 'application/json; charset=utf8; foo=baz'
},
body: ''
})
t.same(response.statusCode, 415)
})
test('content-type fail when parameters not match - regexp', async t => {
t.plan(1)
const fastify = Fastify()
fastify.removeAllContentTypeParsers()
fastify.addContentTypeParser(/application\/json; charset=utf8; foo=bar/, function (request, body, done) {
t.fail('shouldn\'t be called')
done(null, body)
})
fastify.post('/', async () => {
return 'ok'
})
const response = await fastify.inject({
method: 'POST',
path: '/',
headers: {
'content-type': 'application/json; charset=utf8'
},
body: ''
})
t.same(response.statusCode, 415)
})

@@ -1123,3 +1123,3 @@ 'use strict'

headers: {
'Content-Type': 'application/json charset=utf-8'
'Content-Type': 'application/json; charset=utf-8'
}

@@ -1307,3 +1307,3 @@ }, (err, response, body) => {

headers: {
'Content-Type': 'weird-content-type+json'
'Content-Type': 'weird/content-type+json'
}

@@ -1338,3 +1338,3 @@ }, (err, response, body) => {

fastify.addContentTypeParser(/.*\+myExtension$/, function (req, payload, done) {
fastify.addContentTypeParser(/.*\+myExtension$/i, function (req, payload, done) {
let data = ''

@@ -1341,0 +1341,0 @@ payload.on('data', chunk => { data += chunk })

@@ -5,2 +5,3 @@ 'use strict'

const t = require('tap')
const semver = require('semver')
const test = t.test

@@ -157,3 +158,3 @@ const Fastify = require('..')

test('default clientError handler destroys sockets in writable state', t => {
t.plan(1)
t.plan(2)

@@ -174,2 +175,5 @@ const fastify = Fastify({

t.pass('destroy should be called')
},
write (response) {
t.match(response, /^HTTP\/1.1 400 Bad Request/)
}

@@ -195,2 +199,5 @@ })

t.pass('destroy should be called')
},
write (response) {
t.fail('write should not be called')
}

@@ -280,1 +287,40 @@ })

})
const skip = semver.lt(process.versions.node, '11.0.0')
test('default clientError replies with bad request on reused keep-alive connection', { skip }, t => {
t.plan(2)
let response = ''
const fastify = Fastify({
bodyLimit: 1,
keepAliveTimeout: 100
})
fastify.get('/', (request, reply) => {
reply.send('OK\n')
})
fastify.listen({ port: 0 }, function (err) {
t.error(err)
fastify.server.unref()
const client = connect(fastify.server.address().port)
client.on('data', chunk => {
response += chunk.toString('utf-8')
})
client.on('end', () => {
t.match(response, /^HTTP\/1.1 200 OK.*HTTP\/1.1 400 Bad Request/s)
})
client.resume()
client.write('GET / HTTP/1.1\r\n')
client.write('\r\n\r\n')
client.write('GET /?a b HTTP/1.1\r\n')
client.write('Connection: close\r\n')
client.write('\r\n\r\n')
})
})

@@ -686,1 +686,49 @@ 'use strict'

})
test('reply.send handles aborted requests', t => {
t.plan(2)
const spyLogger = {
level: 'error',
fatal: () => { },
error: () => {
t.fail('should not log an error')
},
warn: () => { },
info: () => { },
debug: () => { },
trace: () => { },
child: () => { return spyLogger }
}
const fastify = Fastify({
logger: spyLogger
})
fastify.get('/', (req, reply) => {
setTimeout(() => {
const stream = new Readable({
read: function () {
this.push(null)
}
})
reply.send(stream)
}, 6)
})
fastify.listen({ port: 0 }, err => {
t.error(err)
fastify.server.unref()
const port = fastify.server.address().port
const http = require('http')
const req = http.get(`http://localhost:${port}`)
.on('error', (err) => {
t.equal(err.code, 'ECONNRESET')
fastify.close()
})
setTimeout(() => {
req.abort()
}, 1)
})
})

@@ -1,2 +0,2 @@

import { FastifyError } from 'fastify-error'
import { FastifyError } from '@fastify/error'
import { expectAssignable, expectError, expectType } from 'tsd'

@@ -3,0 +3,0 @@ import fastify, {

@@ -1,2 +0,2 @@

import { expectType } from 'tsd'
import { expectError, expectType } from 'tsd'
import fastify, { FastifyLogFn, LogLevel, FastifyLoggerInstance, FastifyError, FastifyRequest, FastifyReply } from '../../fastify'

@@ -186,1 +186,13 @@ import { Server, IncomingMessage, ServerResponse } from 'http'

})
const childParent = fastify().log
// we test different option variant here
expectType<FastifyLoggerInstance>(childParent.child({}, { level: 'info' }))
expectType<FastifyLoggerInstance>(childParent.child({}, { redact: ['pass', 'pin'] }))
expectType<FastifyLoggerInstance>(childParent.child({}, { serializers: { key: () => {} } }))
expectType<FastifyLoggerInstance>(childParent.child({}, { level: 'info', redact: ['pass', 'pin'], serializers: { key: () => {} } }))
// no option pass
expectError(childParent.child())
// wrong option
expectError(childParent.child({}, { nonExist: true }))

@@ -6,3 +6,3 @@ import fastify, { FastifyInstance, FastifyPluginOptions } from '../../fastify'

import { FastifyPluginCallback, FastifyPluginAsync } from '../../types/plugin'
import { FastifyError } from 'fastify-error'
import { FastifyError } from '@fastify/error'

@@ -9,0 +9,0 @@ // FastifyPlugin & FastifyRegister

@@ -6,3 +6,3 @@ import fastify, { FastifyInstance, FastifyRequest, FastifyReply, RouteHandlerMethod } from '../../fastify'

import { RequestPayload } from '../../types/hooks'
import { FastifyError } from 'fastify-error'
import { FastifyError } from '@fastify/error'

@@ -9,0 +9,0 @@ /*

@@ -7,3 +7,3 @@ import { Readable } from 'stream'

import { FastifyReply } from './reply'
import { FastifyError } from 'fastify-error'
import { FastifyError } from '@fastify/error'
import { FastifyLoggerInstance } from './logger'

@@ -10,0 +10,0 @@ import { RegisterOptions } from './register'

@@ -16,3 +16,3 @@ import { Chain as LightMyRequestChain, InjectOptions, Response as LightMyRequestResponse, CallbackFunc as LightMyRequestCallback } from 'light-my-request'

import { FastifyReply } from './reply'
import { FastifyError } from 'fastify-error'
import { FastifyError } from '@fastify/error'
import { AddContentTypeParser, hasContentTypeParser, getDefaultJsonParser, ProtoAction, ConstructorAction, FastifyBodyParser, removeContentTypeParser, removeAllContentTypeParsers } from './content-type-parser'

@@ -19,0 +19,0 @@

@@ -21,3 +21,3 @@ /*

import { FastifyError } from 'fastify-error'
import { FastifyError } from '@fastify/error'
import { RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression } from './utils'

@@ -40,2 +40,7 @@ import { RouteGenericInterface } from './route'

export interface redactOptions {
paths: string[];
censor?: string | ((v: any) => any) | undefined;
remove?: boolean | undefined;
}
export interface Bindings {

@@ -47,2 +52,8 @@ level?: LogLevel | string;

export interface ChildLoggerOptions {
level?: LogLevel | string;
redact?: string[] | redactOptions | undefined;
serializers?: { [key: string]: SerializerFn } | undefined;
}
export interface FastifyLoggerInstance {

@@ -55,3 +66,3 @@ info: FastifyLogFn;

debug: FastifyLogFn;
child(bindings: Bindings): FastifyLoggerInstance;
child(bindings: Bindings, options?: ChildLoggerOptions): FastifyLoggerInstance;
}

@@ -58,0 +69,0 @@

@@ -8,3 +8,3 @@ import { FastifyInstance } from './instance'

import { preValidationHookHandler, preHandlerHookHandler, preSerializationHookHandler, onRequestHookHandler, preParsingHookHandler, onResponseHookHandler, onSendHookHandler, onErrorHookHandler, onTimeoutHookHandler } from './hooks'
import { FastifyError } from 'fastify-error'
import { FastifyError } from '@fastify/error'
import { FastifyContext } from './context'

@@ -11,0 +11,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc