fastify 4.6.0 → 4.7.0

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.
Files changed (39) hide show
  1. package/docs/Guides/Ecosystem.md +19 -8
  2. package/docs/Guides/Plugins-Guide.md +44 -0
  3. package/docs/Reference/Reply.md +5 -5
  4. package/docs/Reference/Request.md +19 -6
  5. package/docs/Reference/Routes.md +2 -2
  6. package/docs/Reference/Type-Providers.md +3 -3
  7. package/fastify.js +1 -1
  8. package/lib/contentTypeParser.js +10 -9
  9. package/lib/context.js +27 -3
  10. package/lib/error-handler.js +7 -3
  11. package/lib/handleRequest.js +15 -13
  12. package/lib/reply.js +42 -34
  13. package/lib/request.js +36 -18
  14. package/lib/route.js +16 -10
  15. package/lib/schema-controller.js +7 -1
  16. package/lib/server.js +2 -2
  17. package/lib/symbols.js +2 -0
  18. package/lib/validation.js +4 -3
  19. package/lib/warnings.js +2 -0
  20. package/package.json +26 -26
  21. package/test/404s.test.js +19 -1
  22. package/test/context-config.test.js +2 -1
  23. package/test/handler-context.test.js +12 -30
  24. package/test/internals/contentTypeParser.test.js +3 -3
  25. package/test/internals/handleRequest.test.js +4 -3
  26. package/test/internals/reply-serialize.test.js +9 -9
  27. package/test/internals/reply.test.js +10 -9
  28. package/test/internals/request-validate.test.js +97 -9
  29. package/test/internals/request.test.js +57 -3
  30. package/test/internals/validation.test.js +15 -0
  31. package/test/plugin.test.js +1 -1
  32. package/test/reply-code.test.js +59 -0
  33. package/test/route.test.js +29 -0
  34. package/test/router-options.test.js +33 -66
  35. package/test/schema-feature.test.js +25 -0
  36. package/test/schema-validation.test.js +19 -0
  37. package/test/search.test.js +169 -30
  38. package/test/server.test.js +54 -0
  39. package/types/request.d.ts +9 -3
@@ -80,6 +80,8 @@ section.
80
80
  [Next](https://github.com/zeit/next.js/).
81
81
  - [`@fastify/oauth2`](https://github.com/fastify/fastify-oauth2) Wrap around
82
82
  [`simple-oauth2`](https://github.com/lelylan/simple-oauth2).
83
+ - [`@fastify/one-line-logger`](https://github.com/fastify/one-line-logger) Formats
84
+ Fastify's logs into a nice one-line message.
83
85
  - [`@fastify/postgres`](https://github.com/fastify/fastify-postgres) Fastify
84
86
  PostgreSQL connection plugin, with this you can share the same PostgreSQL
85
87
  connection pool in every part of your server.
@@ -119,10 +121,10 @@ section.
119
121
  - [`@fastify/type-provider-json-schema-to-ts`](https://github.com/fastify/fastify-type-provider-json-schema-to-ts)
120
122
  Fastify
121
123
  [type provider](https://www.fastify.io/docs/latest/Reference/Type-Providers/)
122
- for [json-schema-to-ts](https://github.com/ThomasAribart/json-schema-to-ts).
124
+ for [json-schema-to-ts](https://github.com/ThomasAribart/json-schema-to-ts).
123
125
  - [`@fastify/type-provider-typebox`](https://github.com/fastify/fastify-type-provider-typebox)
124
126
  Fastify
125
- [type provider](https://www.fastify.io/docs/latest/Reference/Type-Providers/)
127
+ [type provider](https://www.fastify.io/docs/latest/Reference/Type-Providers/)
126
128
  for [Typebox](https://github.com/sinclairzx81/typebox).
127
129
  - [`@fastify/under-pressure`](https://github.com/fastify/under-pressure) Measure
128
130
  process load with automatic handling of _"Service Unavailable"_ plugin for
@@ -167,7 +169,7 @@ section.
167
169
  Sentry errors handler that just works! Install, add your DSN and you're good
168
170
  to go!
169
171
  - [`@mateonunez/fastify-lyra`](https://github.com/mateonunez/fastify-lyra)
170
- A plugin to implement [Lyra](https://github.com/nearform/lyra) search engine
172
+ A plugin to implement [Lyra](https://github.com/nearform/lyra) search engine
171
173
  on Fastify
172
174
  - [`@mgcrea/fastify-graceful-exit`](https://github.com/mgcrea/fastify-graceful-exit)
173
175
  A plugin to close the server gracefully
@@ -191,7 +193,7 @@ section.
191
193
  - [`cls-rtracer`](https://github.com/puzpuzpuz/cls-rtracer) Fastify middleware
192
194
  for CLS-based request ID generation. An out-of-the-box solution for adding
193
195
  request IDs into your logs.
194
- - [`electron-server`](https://github.com/anonrig/electron-server) A plugin for
196
+ - [`electron-server`](https://github.com/anonrig/electron-server) A plugin for
195
197
  using Fastify without the need of consuming a port on Electron apps.
196
198
  - [`fast-water`](https://github.com/tswayne/fast-water) A Fastify plugin for
197
199
  waterline. Decorates Fastify with waterline models.
@@ -446,7 +448,7 @@ section.
446
448
  OrientDB connection plugin, with which you can share the OrientDB connection
447
449
  across every part of your server.
448
450
  - [`fastify-osm`](https://github.com/gzileni/fastify-osm) Fastify
449
- OSM plugin to run overpass queries by OpenStreetMap.
451
+ OSM plugin to run overpass queries by OpenStreetMap.
450
452
  - [`fastify-peekaboo`](https://github.com/simone-sanfratello/fastify-peekaboo)
451
453
  Fastify plugin for memoize responses by expressive settings.
452
454
  - [`fastify-piscina`](https://github.com/piscinajs/fastify-piscina) A worker
@@ -471,6 +473,9 @@ section.
471
473
  [qs](https://github.com/ljharb/qs).
472
474
  - [`fastify-racing`](https://github.com/metcoder95/fastify-racing) Fastify's
473
475
  plugin that adds support to handle an aborted request asynchronous.
476
+ - [`fastify-ravendb`](https://github.com/nearform/fastify-ravendb) RavenDB
477
+ connection plugin. It exposes the same `DocumentStore` (or multiple ones)
478
+ across the whole Fastify application.
474
479
  - [`fastify-raw-body`](https://github.com/Eomm/fastify-raw-body) Add the
475
480
  `request.rawBody` field.
476
481
  - [`fastify-rbac`](https://gitlab.com/m03geek/fastify-rbac) Fastify role-based
@@ -496,7 +501,9 @@ section.
496
501
  - [`fastify-rob-config`](https://github.com/jeromemacias/fastify-rob-config)
497
502
  Fastify Rob-Config integration.
498
503
  - [`fastify-route-group`](https://github.com/TakNePoidet/fastify-route-group)
499
- Convenient grouping and inheritance of routes
504
+ Convenient grouping and inheritance of routes.
505
+ - [`fastify-s3-buckets`](https://github.com/kibertoad/fastify-s3-buckets)
506
+ Ensure the existence of defined S3 buckets on the application startup.
500
507
  - [`fastify-schema-constraint`](https://github.com/Eomm/fastify-schema-constraint)
501
508
  Choose the JSON schema to use based on request parameters.
502
509
  - [`fastify-schema-to-typescript`](https://github.com/thomasthiebaud/fastify-schema-to-typescript)
@@ -512,11 +519,15 @@ section.
512
519
  `fastify-caching`.
513
520
  - [`fastify-slonik`](https://github.com/Unbuttun/fastify-slonik) Fastify Slonik
514
521
  plugin, with this you can use slonik in every part of your server.
522
+ - [`fastify-slow-down`](https://github.com/nearform/fastify-slow-down) A plugin
523
+ to delay the response from the server.
515
524
  - [`fastify-socket.io`](https://github.com/alemagio/fastify-socket.io) a
516
525
  Socket.io plugin for Fastify.
517
526
  - [`fastify-split-validator`](https://github.com/MetCoder95/fastify-split-validator)
518
527
  Small plugin to allow you use multiple validators in one route based on each
519
528
  HTTP part of the request.
529
+ - [`fastify-sqlite`](https://github.com/Eomm/fastify-sqlite) connects your
530
+ application to a sqlite3 database.
520
531
  - [`fastify-sse`](https://github.com/lolo32/fastify-sse) to provide Server-Sent
521
532
  Events with `reply.sse( … )` to Fastify.
522
533
  - [`fastify-sse-v2`](https://github.com/nodefactoryio/fastify-sse-v2) to provide
@@ -541,8 +552,8 @@ section.
541
552
  - [`fastify-twitch-ebs-tools`](https://github.com/lukemnet/fastify-twitch-ebs-tools)
542
553
  Useful functions for Twitch Extension Backend Services (EBS).
543
554
  - [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod)
544
- Fastify
545
- [type provider](https://www.fastify.io/docs/latest/Reference/Type-Providers/)
555
+ Fastify
556
+ [type provider](https://www.fastify.io/docs/latest/Reference/Type-Providers/)
546
557
  for [zod](https://github.com/colinhacks/zod).
547
558
  - [`fastify-typeorm-plugin`](https://github.com/inthepocket/fastify-typeorm-plugin)
548
559
  Fastify plugin to work with TypeORM.
@@ -308,6 +308,50 @@ fastify.get('/plugin2', (request, reply) => {
308
308
  ```
309
309
  Now your hook will run just for the first route!
310
310
 
311
+ An alternative approach is to make use of the [onRoute hook](../Reference/Hooks.md#onroute)
312
+ to customize application routes dynamically from inside the plugin. Every time
313
+ a new route is registered, you can read and modify the route options. For example,
314
+ based on a [route config option](../Reference/Routes.md#routes-options):
315
+
316
+ ```js
317
+ fastify.register((instance, opts, done) => {
318
+ instance.decorate('util', (request, key, value) => { request[key] = value })
319
+
320
+ function handler(request, reply, done) {
321
+ instance.util(request, 'timestamp', new Date())
322
+ done()
323
+ }
324
+
325
+ instance.addHook('onRoute', (routeOptions) => {
326
+ if (routeOptions.config && routeOptions.config.useUtil === true) {
327
+ // set or add our handler to the route preHandler hook
328
+ if (!routeOptions.preHandler) {
329
+ routeOptions.preHandler = [handler]
330
+ return
331
+ }
332
+ if (Array.isArray(routeOptions.preHandler)) {
333
+ routeOptions.preHandler.push(handler)
334
+ return
335
+ }
336
+ routeOptions.preHandler = [routeOptions.preHandler, handler]
337
+ }
338
+ })
339
+
340
+ fastify.get('/plugin1', {config: {useUtil: true}}, (request, reply) => {
341
+ reply.send(request)
342
+ })
343
+
344
+ fastify.get('/plugin2', (request, reply) => {
345
+ reply.send(request)
346
+ })
347
+
348
+ done()
349
+ })
350
+ ```
351
+
352
+ This variant becomes extremely useful if you plan to distribute your plugin, as
353
+ described in the next section.
354
+
311
355
  As you probably noticed by now, `request` and `reply` are not the standard
312
356
  Nodejs *request* and *response* objects, but Fastify's objects.
313
357
 
@@ -7,22 +7,22 @@
7
7
  - [.statusCode](#statuscode)
8
8
  - [.server](#server)
9
9
  - [.header(key, value)](#headerkey-value)
10
- - [set-cookie](#set-cookie)
11
10
  - [.headers(object)](#headersobject)
12
11
  - [.getHeader(key)](#getheaderkey)
13
12
  - [.getHeaders()](#getheaders)
13
+ - [set-cookie](#set-cookie)
14
14
  - [.removeHeader(key)](#removeheaderkey)
15
15
  - [.hasHeader(key)](#hasheaderkey)
16
16
  - [.trailer(key, function)](#trailerkey-function)
17
17
  - [.hasTrailer(key)](#hastrailerkey)
18
18
  - [.removeTrailer(key)](#removetrailerkey)
19
- - [.redirect([code,] dest)](#redirectcode--dest)
19
+ - [.redirect([code ,] dest)](#redirectcode--dest)
20
20
  - [.callNotFound()](#callnotfound)
21
21
  - [.getResponseTime()](#getresponsetime)
22
22
  - [.type(contentType)](#typecontenttype)
23
- - [.getSerializationFunction(schema | httpStatus)](#getserializationfunction)
24
- - [.compileSerializationSchema(schema, httpStatus)](#compileserializationschema)
25
- - [.serializeInput(data, [schema | httpStatus], [httpStatus])](#serializeinput)
23
+ - [.getSerializationFunction(schema | httpStatus)](#getserializationfunctionschema--httpstatus)
24
+ - [.compileSerializationSchema(schema, httpStatus)](#compileserializationschemaschema-httpstatus)
25
+ - [.serializeInput(data, [schema | httpStatus], [httpStatus])](#serializeinputdata-schema--httpstatus-httpstatus)
26
26
  - [.serializer(func)](#serializerfunc)
27
27
  - [.raw](#raw)
28
28
  - [.sent](#sent)
@@ -35,6 +35,13 @@ Request is a core Fastify object containing the following fields:
35
35
  - `connection` - Deprecated, use `socket` instead. The underlying connection of
36
36
  the incoming request.
37
37
  - `socket` - the underlying connection of the incoming request
38
+ - `context` - A Fastify internal object. You should not use it directly or
39
+ modify it. It is useful to access one special key:
40
+ - `context.config` - The route [`config`](./Routes.md#routes-config) object.
41
+ - `routeSchema` - the scheme definition set for the router that is
42
+ handling the request
43
+ - `routeConfig` - The route [`config`](./Routes.md#routes-config)
44
+ object.
38
45
  - [.getValidationFunction(schema | httpPart)](#getvalidationfunction) -
39
46
  Returns a validation function for the specified schema or http part,
40
47
  if any of either are set or cached.
@@ -48,9 +55,6 @@ Request is a core Fastify object containing the following fields:
48
55
  schema and returns the serialized payload. If the optional
49
56
  `httpPart` is provided, the function will use the serializer
50
57
  function given for that HTTP Status Code. Defaults to `null`.
51
- - `context` - A Fastify internal object. You should not use it directly or
52
- modify it. It is useful to access one special key:
53
- - `context.config` - The route [`config`](./Routes.md#routes-config) object.
54
58
 
55
59
  ### Headers
56
60
 
@@ -98,6 +102,9 @@ it will return a `validation` function that can be used to
98
102
  validate diverse inputs. It returns `undefined` if no
99
103
  serialization function was found using either of the provided inputs.
100
104
 
105
+ This function has property errors. Errors encountered during the last validation
106
+ are assigned to errors
107
+
101
108
  ```js
102
109
  const validate = request
103
110
  .getValidationFunction({
@@ -108,13 +115,15 @@ const validate = request
108
115
  }
109
116
  }
110
117
  })
111
- validate({ foo: 'bar' }) // true
118
+ console.log(validate({ foo: 'bar' })) // true
119
+ console.log(validate.errors) // null
112
120
 
113
121
  // or
114
122
 
115
123
  const validate = request
116
124
  .getValidationFunction('body')
117
- validate({ foo: 0.5 }) // false
125
+ console.log(validate({ foo: 0.5 })) // false
126
+ console.log(validate.errors) // validation errors
118
127
  ```
119
128
 
120
129
  See [.compilaValidationSchema(schema, [httpStatus])](#compilevalidationschema)
@@ -133,6 +142,8 @@ The optional parameter `httpPart`, if provided, is forwarded directly
133
142
  the `ValidationCompiler`, so it can be used to compile the validation
134
143
  function if a custom `ValidationCompiler` is provided for the route.
135
144
 
145
+ This function has property errors. Errors encountered during the last validation
146
+ are assigned to errors
136
147
 
137
148
  ```js
138
149
  const validate = request
@@ -145,6 +156,7 @@ const validate = request
145
156
  }
146
157
  })
147
158
  console.log(validate({ foo: 'bar' })) // true
159
+ console.log(validate.errors) // null
148
160
 
149
161
  // or
150
162
 
@@ -158,6 +170,7 @@ const validate = request
158
170
  }
159
171
  }, 200)
160
172
  console.log(validate({ hello: 'world' })) // false
173
+ console.log(validate.errors) // validation errors
161
174
  ```
162
175
 
163
176
  Note that you should be careful when using this function, as it will cache
@@ -247,4 +260,4 @@ request
247
260
  ```
248
261
 
249
262
  See [.compileValidationSchema(schema, [httpStatus])](#compileValidationSchema)
250
- for more information on how to compile validation schemas.
263
+ for more information on how to compile validation schemas.
@@ -41,8 +41,8 @@ fastify.route(options)
41
41
  need to be in [JSON Schema](https://json-schema.org/) format, check
42
42
  [here](./Validation-and-Serialization.md) for more info.
43
43
 
44
- * `body`: validates the body of the request if it is a POST, PUT, or PATCH
45
- method.
44
+ * `body`: validates the body of the request if it is a POST, PUT, PATCH,
45
+ TRACE, or SEARCH method.
46
46
  * `querystring` or `query`: validates the querystring. This can be a complete
47
47
  JSON Schema object, with the property `type` of `object` and `properties`
48
48
  object of parameters, or simply the values of what would be contained in the
@@ -148,7 +148,7 @@ fastify.register(pluginWithTypebox)
148
148
 
149
149
  It's also important to mention that once the types don't propagate globally,
150
150
  _currently_ is not possible to avoid multiple registrations on routes when
151
- dealing with several scopes, see bellow:
151
+ dealing with several scopes, see below:
152
152
 
153
153
  ```ts
154
154
  import Fastify from 'fastify'
@@ -218,7 +218,7 @@ server.listen({ port: 3000 })
218
218
  import { Type } from '@sinclair/typebox'
219
219
  import {
220
220
  FastifyInstance,
221
- FastifyLoggerInstance,
221
+ FastifyBaseLogger,
222
222
  RawReplyDefaultExpression,
223
223
  RawRequestDefaultExpression,
224
224
  RawServerDefault
@@ -229,7 +229,7 @@ type FastifyTypebox = FastifyInstance<
229
229
  RawServerDefault,
230
230
  RawRequestDefaultExpression<RawServerDefault>,
231
231
  RawReplyDefaultExpression<RawServerDefault>,
232
- FastifyLoggerInstance,
232
+ FastifyBaseLogger,
233
233
  TypeBoxTypeProvider
234
234
  >;
235
235
 
package/fastify.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const VERSION = '4.6.0'
3
+ const VERSION = '4.7.0'
4
4
 
5
5
  const Avvio = require('avvio')
6
6
  const http = require('http')
@@ -1,11 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { AsyncResource } = require('async_hooks')
4
- let lru = require('tiny-lru')
5
- // Needed to handle Webpack and faux modules
6
- // See https://github.com/fastify/fastify/issues/2356
7
- // and https://github.com/fastify/fastify/discussions/2907.
8
- lru = typeof lru === 'function' ? lru : lru.default
4
+ const lru = require('tiny-lru').lru
9
5
 
10
6
  const secureJson = require('secure-json-parse')
11
7
  const {
@@ -15,7 +11,8 @@ const {
15
11
  kRequestPayloadStream,
16
12
  kState,
17
13
  kTestInternals,
18
- kReplyIsError
14
+ kReplyIsError,
15
+ kRouteContext
19
16
  } = require('./symbols')
20
17
 
21
18
  const {
@@ -149,12 +146,16 @@ ContentTypeParser.prototype.run = function (contentType, handler, request, reply
149
146
  const resource = new AsyncResource('content-type-parser:run', request)
150
147
 
151
148
  if (parser === undefined) {
152
- reply.send(new FST_ERR_CTP_INVALID_MEDIA_TYPE(contentType || undefined))
149
+ if (request.is404) {
150
+ handler(request, reply)
151
+ } else {
152
+ reply.send(new FST_ERR_CTP_INVALID_MEDIA_TYPE(contentType || undefined))
153
+ }
153
154
  } else if (parser.asString === true || parser.asBuffer === true) {
154
155
  rawBody(
155
156
  request,
156
157
  reply,
157
- reply.context._parserOptions,
158
+ reply[kRouteContext]._parserOptions,
158
159
  parser,
159
160
  done
160
161
  )
@@ -185,7 +186,7 @@ function rawBody (request, reply, options, parser, done) {
185
186
  const limit = options.limit === null ? parser.bodyLimit : options.limit
186
187
  const contentLength = request.headers['content-length'] === undefined
187
188
  ? NaN
188
- : Number.parseInt(request.headers['content-length'], 10)
189
+ : Number(request.headers['content-length'])
189
190
 
190
191
  if (contentLength > limit) {
191
192
  reply.send(new FST_ERR_CTP_BODY_TOO_LARGE())
package/lib/context.js CHANGED
@@ -12,10 +12,11 @@ const {
12
12
  kContentTypeParser,
13
13
  kRouteByFastify,
14
14
  kRequestValidateWeakMap,
15
- kReplySerializeWeakMap
15
+ kReplySerializeWeakMap,
16
+ kPublicRouteContext
16
17
  } = require('./symbols.js')
17
18
 
18
- // Objects that holds the context of every request
19
+ // Object that holds the context of every request
19
20
  // Every route holds an instance of this object.
20
21
  function Context ({
21
22
  schema,
@@ -56,7 +57,10 @@ function Context ({
56
57
  this[kFourOhFourContext] = null
57
58
  this.attachValidation = attachValidation
58
59
  this[kReplySerializerDefault] = replySerializer
59
- this.schemaErrorFormatter = schemaErrorFormatter || server[kSchemaErrorFormatter] || defaultSchemaErrorFormatter
60
+ this.schemaErrorFormatter =
61
+ schemaErrorFormatter ||
62
+ server[kSchemaErrorFormatter] ||
63
+ defaultSchemaErrorFormatter
60
64
  this[kRouteByFastify] = isFastify
61
65
 
62
66
  this[kRequestValidateWeakMap] = null
@@ -64,9 +68,29 @@ function Context ({
64
68
  this.validatorCompiler = validatorCompiler || null
65
69
  this.serializerCompiler = serializerCompiler || null
66
70
 
71
+ // Route + Userland configurations for the route
72
+ this[kPublicRouteContext] = getPublicRouteContext(this)
73
+
67
74
  this.server = server
68
75
  }
69
76
 
77
+ function getPublicRouteContext (context) {
78
+ return Object.create(null, {
79
+ schema: {
80
+ enumerable: true,
81
+ get () {
82
+ return context.schema
83
+ }
84
+ },
85
+ config: {
86
+ enumerable: true,
87
+ get () {
88
+ return context.config
89
+ }
90
+ }
91
+ })
92
+ }
93
+
70
94
  function defaultSchemaErrorFormatter (errors, dataVar) {
71
95
  let text = ''
72
96
  const separator = ', '
@@ -3,7 +3,11 @@
3
3
  const statusCodes = require('http').STATUS_CODES
4
4
  const wrapThenable = require('./wrapThenable')
5
5
  const {
6
- kReplyHeaders, kReplyNextErrorHandler, kReplyIsRunningOnErrorHook, kReplyHasStatusCode
6
+ kReplyHeaders,
7
+ kReplyNextErrorHandler,
8
+ kReplyIsRunningOnErrorHook,
9
+ kReplyHasStatusCode,
10
+ kRouteContext
7
11
  } = require('./symbols.js')
8
12
 
9
13
  const {
@@ -24,7 +28,7 @@ const rootErrorHandler = {
24
28
  function handleError (reply, error, cb) {
25
29
  reply[kReplyIsRunningOnErrorHook] = false
26
30
 
27
- const context = reply.context
31
+ const context = reply[kRouteContext]
28
32
  if (reply[kReplyNextErrorHandler] === false) {
29
33
  fallbackErrorHandler(error, reply, function (reply, payload) {
30
34
  try {
@@ -90,7 +94,7 @@ function fallbackErrorHandler (error, reply, cb) {
90
94
  const statusCode = reply.statusCode
91
95
  let payload
92
96
  try {
93
- const serializerFn = getSchemaSerializer(reply.context, statusCode)
97
+ const serializerFn = getSchemaSerializer(reply[kRouteContext], statusCode)
94
98
  payload = (serializerFn === false)
95
99
  ? serializeError({
96
100
  error: statusCodes[statusCode + ''],
@@ -4,7 +4,8 @@ const { validate: validateSchema } = require('./validation')
4
4
  const { hookRunner, hookIterator } = require('./hooks')
5
5
  const wrapThenable = require('./wrapThenable')
6
6
  const {
7
- kReplyIsError
7
+ kReplyIsError,
8
+ kRouteContext
8
9
  } = require('./symbols')
9
10
 
10
11
  function handleRequest (err, request, reply) {
@@ -17,15 +18,16 @@ function handleRequest (err, request, reply) {
17
18
 
18
19
  const method = request.raw.method
19
20
  const headers = request.headers
21
+ const context = request[kRouteContext]
20
22
 
21
- if (method === 'GET' || method === 'HEAD' || method === 'SEARCH') {
23
+ if (method === 'GET' || method === 'HEAD') {
22
24
  handler(request, reply)
23
25
  return
24
26
  }
25
27
 
26
28
  const contentType = headers['content-type']
27
29
 
28
- if (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'TRACE') {
30
+ if (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'TRACE' || method === 'SEARCH') {
29
31
  if (contentType === undefined) {
30
32
  if (
31
33
  headers['transfer-encoding'] === undefined &&
@@ -33,10 +35,10 @@ function handleRequest (err, request, reply) {
33
35
  ) { // Request has no body to parse
34
36
  handler(request, reply)
35
37
  } else {
36
- reply.context.contentTypeParser.run('', handler, request, reply)
38
+ context.contentTypeParser.run('', handler, request, reply)
37
39
  }
38
40
  } else {
39
- reply.context.contentTypeParser.run(contentType, handler, request, reply)
41
+ context.contentTypeParser.run(contentType, handler, request, reply)
40
42
  }
41
43
  return
42
44
  }
@@ -49,7 +51,7 @@ function handleRequest (err, request, reply) {
49
51
  headers['content-length'] !== undefined
50
52
  )
51
53
  ) {
52
- reply.context.contentTypeParser.run(contentType, handler, request, reply)
54
+ context.contentTypeParser.run(contentType, handler, request, reply)
53
55
  } else {
54
56
  handler(request, reply)
55
57
  }
@@ -62,9 +64,9 @@ function handleRequest (err, request, reply) {
62
64
 
63
65
  function handler (request, reply) {
64
66
  try {
65
- if (reply.context.preValidation !== null) {
67
+ if (request[kRouteContext].preValidation !== null) {
66
68
  hookRunner(
67
- reply.context.preValidation,
69
+ request[kRouteContext].preValidation,
68
70
  hookIterator,
69
71
  request,
70
72
  reply,
@@ -87,9 +89,9 @@ function preValidationCallback (err, request, reply) {
87
89
  return
88
90
  }
89
91
 
90
- const result = validateSchema(reply.context, request)
92
+ const result = validateSchema(reply[kRouteContext], request)
91
93
  if (result) {
92
- if (reply.context.attachValidation === false) {
94
+ if (reply[kRouteContext].attachValidation === false) {
93
95
  reply.send(result)
94
96
  return
95
97
  }
@@ -98,9 +100,9 @@ function preValidationCallback (err, request, reply) {
98
100
  }
99
101
 
100
102
  // preHandler hook
101
- if (reply.context.preHandler !== null) {
103
+ if (request[kRouteContext].preHandler !== null) {
102
104
  hookRunner(
103
- reply.context.preHandler,
105
+ request[kRouteContext].preHandler,
104
106
  hookIterator,
105
107
  request,
106
108
  reply,
@@ -123,7 +125,7 @@ function preHandlerCallback (err, request, reply) {
123
125
  let result
124
126
 
125
127
  try {
126
- result = reply.context.handler(request, reply)
128
+ result = request[kRouteContext].handler(request, reply)
127
129
  } catch (err) {
128
130
  reply[kReplyIsError] = true
129
131
  reply.send(err)