Aktueller Stand

This commit is contained in:
2026-01-22 19:05:45 +01:00
parent 85dee61a4d
commit e280e4eadb
1967 changed files with 397327 additions and 74093 deletions

View File

@@ -1,15 +1,6 @@
'use strict'
const proxyAddr = require('proxy-addr')
const semver = require('semver')
const {
FSTDEP005,
FSTDEP012,
FSTDEP015,
FSTDEP016,
FSTDEP017,
FSTDEP018
} = require('./warnings')
const proxyAddr = require('@fastify/proxy-addr')
const {
kHasBeenDecorated,
kSchemaBody,
@@ -20,10 +11,10 @@ const {
kOptions,
kRequestCacheValidateFns,
kRouteContext,
kPublicRouteContext,
kRequestOriginalUrl
} = require('./symbols')
const { FST_ERR_REQ_INVALID_VALIDATION_INVOCATION } = require('./errors')
const { FST_ERR_REQ_INVALID_VALIDATION_INVOCATION, FST_ERR_DEC_UNDECLARED } = require('./errors')
const decorators = require('./decorate')
const HTTP_PART_SYMBOL_MAP = {
body: kSchemaBody,
@@ -49,8 +40,8 @@ function getTrustProxyFn (tp) {
return tp
}
if (tp === true) {
// Support plain true/false
return function () { return true }
// Support trusting everything
return null
}
if (typeof tp === 'number') {
// Support trusting hop count
@@ -83,10 +74,8 @@ function buildRegularRequest (R) {
this.log = log
this.body = undefined
// eslint-disable-next-line no-var
var prop
// eslint-disable-next-line no-var
for (var i = 0; i < props.length; i++) {
let prop
for (let i = 0; i < props.length; i++) {
prop = props[i]
this[prop.key] = prop.value
}
@@ -115,7 +104,8 @@ function buildRequestWithTrustProxy (R, trustProxy) {
Object.defineProperties(_Request.prototype, {
ip: {
get () {
return proxyAddr(this.raw, proxyFn)
const addrs = proxyAddr.all(this.raw, proxyFn)
return addrs[addrs.length - 1]
}
},
ips: {
@@ -123,12 +113,18 @@ function buildRequestWithTrustProxy (R, trustProxy) {
return proxyAddr.all(this.raw, proxyFn)
}
},
hostname: {
host: {
get () {
if (this.ip !== undefined && this.headers['x-forwarded-host']) {
return getLastEntryInMultiHeaderValue(this.headers['x-forwarded-host'])
}
return this.headers.host || this.headers[':authority']
/**
* The last fallback supports the following cases:
* 1. http.requireHostHeader === false
* 2. HTTP/1.0 without a Host Header
* 3. Headers schema that may remove the Host Header
*/
return this.headers.host ?? this.headers[':authority'] ?? ''
}
},
protocol: {
@@ -146,6 +142,12 @@ function buildRequestWithTrustProxy (R, trustProxy) {
return _Request
}
function assertsRequestDecoration (request, name) {
if (!decorators.hasKey(request, name) && !decorators.exist(request, name)) {
throw new FST_ERR_DEC_UNDECLARED(name, 'request')
}
}
Object.defineProperties(Request.prototype, {
server: {
get () {
@@ -171,18 +173,6 @@ Object.defineProperties(Request.prototype, {
return this.raw.method
}
},
context: {
get () {
FSTDEP012()
return this[kRouteContext]
}
},
routerPath: {
get () {
FSTDEP017()
return this[kRouteContext].config?.url
}
},
routeOptions: {
get () {
const context = this[kRouteContext]
@@ -198,37 +188,12 @@ Object.defineProperties(Request.prototype, {
exposeHeadRoute: context.exposeHeadRoute,
prefixTrailingSlash: context.prefixTrailingSlash,
handler: context.handler,
config: context.config,
schema: context.schema,
version
}
Object.defineProperties(options, {
config: {
get: () => context.config
},
schema: {
get: () => context.schema
}
})
return Object.freeze(options)
}
},
routerMethod: {
get () {
FSTDEP018()
return this[kRouteContext].config?.method
}
},
routeConfig: {
get () {
FSTDEP016()
return this[kRouteContext][kPublicRouteContext]?.config
}
},
routeSchema: {
get () {
FSTDEP015()
return this[kRouteContext][kPublicRouteContext].schema
return options
}
},
is404: {
@@ -236,15 +201,6 @@ Object.defineProperties(Request.prototype, {
return this[kRouteContext].config?.url === undefined
}
},
connection: {
get () {
/* istanbul ignore next */
if (semver.gte(process.versions.node, '13.0.0')) {
FSTDEP005()
}
return this.raw.connection
}
},
socket: {
get () {
return this.raw.socket
@@ -257,9 +213,42 @@ Object.defineProperties(Request.prototype, {
}
}
},
host: {
get () {
/**
* The last fallback supports the following cases:
* 1. http.requireHostHeader === false
* 2. HTTP/1.0 without a Host Header
* 3. Headers schema that may remove the Host Header
*/
return this.raw.headers.host ?? this.raw.headers[':authority'] ?? ''
}
},
hostname: {
get () {
return this.raw.headers.host || this.raw.headers[':authority']
// Check for IPV6 Host
if (this.host[0] === '[') {
return this.host.slice(0, this.host.indexOf(']') + 1)
}
return this.host.split(':', 1)[0]
}
},
port: {
get () {
// first try taking port from host
const portFromHost = parseInt(this.host.split(':').slice(-1)[0])
if (!isNaN(portFromHost)) {
return portFromHost
}
// now fall back to port from host/:authority header
const host = (this.headers.host ?? this.headers[':authority'] ?? '')
const portFromHeader = parseInt(host.split(':').slice(-1)[0])
if (!isNaN(portFromHeader)) {
return portFromHeader
}
// fall back to null
return null
}
},
protocol: {
@@ -299,13 +288,13 @@ Object.defineProperties(Request.prototype, {
}
const validatorCompiler = this[kRouteContext].validatorCompiler ||
this.server[kSchemaController].validatorCompiler ||
(
// We compile the schemas if no custom validatorCompiler is provided
// nor set
this.server[kSchemaController].setupValidator(this.server[kOptions]) ||
this.server[kSchemaController].validatorCompiler
)
this.server[kSchemaController].validatorCompiler ||
(
// We compile the schemas if no custom validatorCompiler is provided
// nor set
this.server[kSchemaController].setupValidator(this.server[kOptions]) ||
this.server[kSchemaController].validatorCompiler
)
const validateFn = validatorCompiler({
schema,
@@ -342,8 +331,8 @@ Object.defineProperties(Request.prototype, {
// We cannot compile if the schema is missed
if (validate == null && (schema == null ||
typeof schema !== 'object' ||
Array.isArray(schema))
typeof schema !== 'object' ||
Array.isArray(schema))
) {
throw new FST_ERR_REQ_INVALID_VALIDATION_INVOCATION(httpPart)
}
@@ -359,6 +348,25 @@ Object.defineProperties(Request.prototype, {
return validate(input)
}
},
getDecorator: {
value: function (name) {
assertsRequestDecoration(this, name)
const decorator = this[name]
if (typeof decorator === 'function') {
return decorator.bind(this)
}
return decorator
}
},
setDecorator: {
value: function (name, value) {
assertsRequestDecoration(this, name)
this[name] = value
}
}
})