@fastify/reply-from 9.4.0 → 9.6.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 (78) hide show
  1. package/.gitattributes +2 -0
  2. package/README.md +78 -22
  3. package/index.js +40 -33
  4. package/lib/request.js +4 -4
  5. package/lib/utils.js +2 -0
  6. package/package.json +4 -2
  7. package/test/async-route-handler.test.js +1 -1
  8. package/test/base-get.test.js +1 -1
  9. package/test/base-querystring.test.js +1 -1
  10. package/test/core-with-path-in-base.test.js +1 -1
  11. package/test/custom-undici-instance.test.js +1 -1
  12. package/test/disable-request-logging.test.js +1 -1
  13. package/test/fastify-multipart-incompatibility.test.js +3 -3
  14. package/test/fix-GHSA-v2v2-hph8-q5xp.test.js +47 -0
  15. package/test/full-get-test.test.js +1 -1
  16. package/test/full-https-get.test.js +3 -3
  17. package/test/full-post-extended-content-type.test.js +1 -1
  18. package/test/full-post-stream-core.test.js +1 -1
  19. package/test/full-post-stream.test.js +1 -1
  20. package/test/full-post.test.js +1 -1
  21. package/test/full-querystring-rewrite-option-complex.test.js +1 -1
  22. package/test/full-querystring-rewrite-option-function.test.js +2 -2
  23. package/test/full-querystring-rewrite-option.test.js +1 -1
  24. package/test/full-querystring-rewrite-string.test.js +1 -1
  25. package/test/full-querystring-rewrite.test.js +1 -1
  26. package/test/full-querystring.test.js +1 -1
  27. package/test/full-rewrite-body-content-type.test.js +1 -1
  28. package/test/full-rewrite-body-http.test.js +1 -1
  29. package/test/full-rewrite-body-to-empty-string.test.js +1 -1
  30. package/test/full-rewrite-body-to-null.test.js +1 -1
  31. package/test/full-rewrite-body.test.js +1 -1
  32. package/test/get-upstream-http.test.js +1 -1
  33. package/test/get-upstream-type.test.js +1 -1
  34. package/test/get-upstream-undici.test.js +1 -1
  35. package/test/get-with-body.test.js +1 -1
  36. package/test/head-with-body.test.js +1 -1
  37. package/test/http-agents.test.js +2 -2
  38. package/test/http-global-agent.test.js +1 -1
  39. package/test/http-retry.test.js +1 -1
  40. package/test/http2-http2.test.js +2 -2
  41. package/test/http2-https.test.js +2 -2
  42. package/test/https-agents.test.js +4 -4
  43. package/test/https-global-agent.test.js +3 -3
  44. package/test/method.test.js +1 -1
  45. package/test/modifyCoreObjects-false.test.js +1 -1
  46. package/test/no-body-opts-with-get.test.js +1 -1
  47. package/test/no-body-opts-with-head.test.js +1 -1
  48. package/test/no-stream-body-option.test.js +2 -2
  49. package/test/onResponse.test.js +1 -1
  50. package/test/padded-body.test.js +1 -1
  51. package/test/post-formbody.test.js +1 -1
  52. package/test/post-plain-text.test.js +1 -1
  53. package/test/post-with-custom-encoded-contenttype.test.js +2 -2
  54. package/test/post-with-octet-stream.test.js +2 -2
  55. package/test/retry-on-503.test.js +1 -1
  56. package/test/retry-with-a-custom-handler.test.js +162 -0
  57. package/test/rewrite-headers-type.test.js +1 -1
  58. package/test/rewrite-headers.test.js +1 -1
  59. package/test/rewrite-request-headers-type.test.js +1 -1
  60. package/test/rewrite-request-headers.test.js +1 -1
  61. package/test/transform-body.test.js +2 -2
  62. package/test/undici-agent.test.js +1 -1
  63. package/test/undici-body.test.js +1 -1
  64. package/test/undici-connect-timeout.test.js +2 -2
  65. package/test/undici-global-agent.test.js +1 -1
  66. package/test/undici-options.test.js +1 -1
  67. package/test/undici-retry.test.js +1 -1
  68. package/test/undici-timeout-body-partial.test.js +1 -1
  69. package/test/undici-timeout-body.test.js +1 -1
  70. package/test/undici-with-path-in-base.test.js +1 -1
  71. package/test/undici.test.js +1 -1
  72. package/test/unix-http-undici-from.test.js +3 -3
  73. package/test/unix-http-undici.test.js +3 -3
  74. package/test/unix-http.test.js +3 -3
  75. package/test/unix-https-undici.test.js +4 -4
  76. package/test/unix-https.test.js +4 -4
  77. package/types/index.d.ts +24 -15
  78. package/types/index.test-d.ts +15 -6
package/.gitattributes ADDED
@@ -0,0 +1,2 @@
1
+ # Set default behavior to automatically convert line endings
2
+ * text=auto eol=lf
package/README.md CHANGED
@@ -14,7 +14,7 @@ npm i @fastify/reply-from
14
14
  ```
15
15
 
16
16
  ## Compatibility with @fastify/multipart
17
- `@fastify/reply-from` and [`@fastify/multipart`](https://github.com/fastify/fastify-multipart) should not be registered as sibling plugins nor should they be registered in plugins which have a parent-child relationship.<br> The two plugins are incompatible, in the sense that the behavior of `@fastify/reply-from` might not be the expected one when the above-mentioned conditions are not respected.<br> This is due to the fact that `@fastify/multipart` consumes the multipart content by parsing it, hence this content is not forwarded to the target service by `@fastify/reply-from`.<br>
17
+ `@fastify/reply-from` and [`@fastify/multipart`](https://github.com/fastify/fastify-multipart) should not be registered as sibling plugins nor should they be registered in plugins which have a parent-child relationship.`<br>` The two plugins are incompatible, in the sense that the behavior of `@fastify/reply-from` might not be the expected one when the above-mentioned conditions are not respected.`<br>` This is due to the fact that `@fastify/multipart` consumes the multipart content by parsing it, hence this content is not forwarded to the target service by `@fastify/reply-from`.`<br>`
18
18
  However, the two plugins may be used within the same fastify instance, at the condition that they belong to disjoint branches of the fastify plugins hierarchy tree.
19
19
 
20
20
  ## Usage
@@ -74,7 +74,7 @@ socket server by using `querystring.escape(socketPath)` as the hostname. This i
74
74
  for http2 nor undici. To illustrate:
75
75
 
76
76
  ```js
77
- const socketPath = require('querystring').escape('/run/http-daemon.socket')
77
+ const socketPath = require('node:querystring').escape('/run/http-daemon.socket')
78
78
  proxy.register(require('@fastify/reply-from'), {
79
79
  base: 'unix+http://${socketPath}/'
80
80
  });
@@ -115,7 +115,7 @@ proxy.register(require('@fastify/reply-from'), {
115
115
 
116
116
  #### `http`
117
117
 
118
- Set the `http` option to an Object to use
118
+ Set the `http` option to an Object to use
119
119
  Node's [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback)
120
120
  will be used if you do not enable [`http2`](#http2). To customize the `request`,
121
121
  you can pass in [`agentOptions`](https://nodejs.org/api/http.html#http_new_agent_options) and
@@ -136,6 +136,7 @@ proxy.register(require('@fastify/reply-from'), {
136
136
  ```
137
137
 
138
138
  You can also pass custom HTTP agents. If you pass the agents, then the http.agentOptions will be ignored. To illustrate:
139
+
139
140
  ```js
140
141
  proxy.register(require('@fastify/reply-from'), {
141
142
  base: 'http://localhost:3001/',
@@ -192,27 +193,27 @@ The number of parsed URLs that will be cached. Default: `100`.
192
193
 
193
194
  #### `disableCache`
194
195
 
195
- This option will disable the URL caching.
196
+ This option will disable the URL caching.
196
197
  This cache is dedicated to reduce the amount of URL object generation.
197
198
  Generating URLs is a main bottleneck of this module, please disable this cache with caution.
198
199
 
199
200
  #### `contentTypesToEncode`
200
201
 
201
- An array of content types whose response body will be passed through `JSON.stringify()`.
202
+ An array of content types whose response body will be passed through `JSON.stringify()`.
202
203
  This only applies when a custom [`body`](#body) is not passed in. Defaults to:
203
204
 
204
205
  ```js
205
- [
206
+ [
206
207
  'application/json'
207
208
  ]
208
209
  ```
209
210
 
210
211
  #### `retryMethods`
211
212
 
212
- On which methods should the connection be retried in case of socket hang up.
213
+ On which methods should the connection be retried in case of socket hang up.
213
214
  **Be aware** that setting here not idempotent method may lead to unexpected results on target.
214
215
 
215
- By default: `['GET', 'HEAD', 'OPTIONS', 'TRACE' ]`
216
+ By default: `['GET', 'HEAD', 'OPTIONS', 'TRACE']`
216
217
 
217
218
  This plugin will always retry on 503 errors, _unless_ `retryMethods` does not contain `GET`.
218
219
 
@@ -221,6 +222,7 @@ This plugin will always retry on 503 errors, _unless_ `retryMethods` does not co
221
222
  Enables the possibility to explictly opt-in for global agents.
222
223
 
223
224
  Usage for undici global agent:
225
+
224
226
  ```js
225
227
  import { setGlobalDispatcher, ProxyAgent } from 'undici'
226
228
 
@@ -234,11 +236,12 @@ fastify.register(FastifyReplyFrom, {
234
236
  ```
235
237
 
236
238
  Usage for http/https global agent:
239
+
237
240
  ```js
238
241
  fastify.register(FastifyReplyFrom, {
239
242
  base: 'http://localhost:3001/',
240
243
  // http and https is allowed to use http.globalAgent or https.globalAgent
241
- globalAgent: true,
244
+ globalAgent: true,
242
245
  http: {
243
246
  }
244
247
  })
@@ -263,7 +266,59 @@ This option set the limit on how many times the plugin should retry the request,
263
266
 
264
267
  By Default: 10
265
268
 
269
+ ---
270
+
271
+ ### `retryDelay`
272
+
273
+ - `handler`. Required
274
+
275
+ This plugin gives the client an option to pass their own retry callback to allow the client to define what retryDelay they would like on any retries
276
+ outside the scope of what is handled by default in fastify-reply-from. To see the default please refer to index.js `getDefaultDelay()`
277
+ If a `handler` is passed to the `retryDelay` object the onus is on the client to invoke the default retry logic in their callback otherwise default cases such as 500 will not be handled
278
+
279
+ - `err` is the error thrown by making a request using whichever agent is configured
280
+ - `req` is the raw request details sent to the underlying agent. __Note__: this object is not a Fastify request object, but instead the low-level request for the agent.
281
+ - `res` is the raw response returned by the underlying agent (if available) __Note__: this object is not a Fastify response, but instead the low-level response from the agent. This property may be null if no response was obtained at all, like from a connection reset or timeout.
282
+ - `attempt` in the object callback refers to the current retriesAttempt number. You are given the freedom to use this in concert with the retryCount property set to handle retries
283
+ - `getDefaultRetry` refers to the default retry handler. If this callback returns not null and you wish to handle those case of errors simply invoke it as done below.
284
+
285
+ Given example
286
+
287
+ ```js
288
+ const customRetryLogic = ({err, req, res, attempt, getDefaultRetry}) => {
289
+ //If this block is not included all non 500 errors will not be retried
290
+ const defaultDelay = getDefaultDelay();
291
+ if (defaultDelay) return defaultDelay();
292
+
293
+ //Custom retry logic
294
+ if (res && res.statusCode === 500 && req.method === 'GET') {
295
+ return 300
296
+ }
297
+
298
+ if (err && err.code == "UND_ERR_SOCKET"){
299
+ return 600
300
+ }
301
+
302
+ return null
303
+ }
304
+
305
+ .......
266
306
 
307
+ fastify.register(FastifyReplyFrom, {
308
+ base: 'http://localhost:3001/',
309
+ retryDelay: customRetryLogic
310
+ })
311
+
312
+ ```
313
+
314
+ Note the Typescript Equivalent
315
+ ```
316
+ const customRetryLogic = ({req, res, err, getDefaultRetry}: RetryDetails) => {
317
+ ...
318
+ }
319
+ ...
320
+
321
+ ```
267
322
  ---
268
323
 
269
324
  ### `reply.from(source, [opts])`
@@ -328,6 +383,7 @@ ContraintStrategies.
328
383
  e.g.:
329
384
 
330
385
  Route grpc-web/http1 and grpc/http2 to different routes with a ContentType-ConstraintStrategy:
386
+
331
387
  ```
332
388
  const contentTypeMatchContraintStrategy = {
333
389
  // strategy name for referencing in the route handler `constraints` options
@@ -341,17 +397,18 @@ const contentTypeMatchContraintStrategy = {
341
397
  }
342
398
  },
343
399
  // function to get the value of the constraint from each incoming request
344
- deriveConstraint: (req: any, ctx: any) => {
400
+ deriveConstraint: (req: any, ctx: any) => {
345
401
  return req.headers['content-type']
346
402
  },
347
403
  // optional flag marking if handlers without constraints can match requests that have a value for this constraint
348
404
  mustMatchWhenDerived: true
349
405
  }
350
-
406
+
351
407
  server.addConstraintStrategy(contentTypeMatchContraintStrategy);
352
408
  ```
353
409
 
354
410
  and then 2 different upstreams with different register's:
411
+
355
412
  ```
356
413
  // grpc-web / http1
357
414
  server.register(fastifyHttpProxy, {
@@ -359,18 +416,17 @@ server.register(fastifyHttpProxy, {
359
416
  // therefore we have to transport to the grpc-web-proxy via http1
360
417
  http2: false,
361
418
  upstream: 'http://grpc-web-proxy',
362
- constraints: { "contentType": "application/grpc-web+proto" }
419
+ constraints: { "contentType": "application/grpc-web+proto" }
363
420
  });
364
421
 
365
422
  // grpc / http2
366
423
  server.register(fastifyHttpProxy, {
367
424
  http2: true,
368
425
  upstream: 'http://grpc.server',
369
- constraints: { "contentType": "application/grpc+proto" }
426
+ constraints: { "contentType": "application/grpc+proto" }
370
427
  });
371
428
  ```
372
429
 
373
-
374
430
  #### `queryString` or `queryString(search, reqUrl)`
375
431
 
376
432
  Replaces the original querystring of the request with what is specified.
@@ -390,12 +446,12 @@ Setting this option to `null` will strip the body (and `content-type` header) en
390
446
 
391
447
  #### `method`
392
448
 
393
- Replaces the original request method with what is specified.
449
+ Replaces the original request method with what is specified.
394
450
 
395
451
  #### `retriesCount`
396
452
 
397
- How many times it will try to pick another connection on socket hangup (`ECONNRESET` error).
398
- Useful when keeping the connection open (KeepAlive).
453
+ How many times it will try to pick another connection on socket hangup (`ECONNRESET` error).
454
+ Useful when keeping the connection open (KeepAlive).
399
455
  This number should be a function of the number of connections and the number of instances of a target.
400
456
 
401
457
  By default: 0 (disabled)
@@ -407,13 +463,13 @@ already overriding the [`body`](#body).
407
463
 
408
464
  ### Combining with [@fastify/formbody](https://github.com/fastify/fastify-formbody)
409
465
 
410
- `formbody` expects the body to be returned as a string and not an object.
466
+ `formbody` expects the body to be returned as a string and not an object.
411
467
  Use the [`contentTypesToEncode`](#contentTypesToEncode) option to pass in `['application/x-www-form-urlencoded']`
412
468
 
413
-
414
469
  ### HTTP & HTTP2 timeouts
415
470
 
416
471
  This library has:
472
+
417
473
  - `timeout` for `http` set by default. The default value is 10 seconds (`10000`).
418
474
  - `requestTimeout` & `sessionTimeout` for `http2` set by default.
419
475
  - The default value for `requestTimeout` is 10 seconds (`10000`).
@@ -426,10 +482,10 @@ will be returned to the client.
426
482
 
427
483
  * [ ] support overriding the body with a stream
428
484
  * [ ] forward the request id to the other peer might require some
429
- refactoring because we have to make the `req.id` unique
430
- (see [hyperid](https://npm.im/hyperid)).
485
+ refactoring because we have to make the `req.id` unique
486
+ (see [hyperid](https://npm.im/hyperid)).
431
487
  * [ ] Support origin HTTP2 push
432
- * [x] benchmarks
488
+ * [X] benchmarks
433
489
 
434
490
  ## License
435
491
 
package/index.js CHANGED
@@ -3,7 +3,8 @@
3
3
  const fp = require('fastify-plugin')
4
4
  const { lru } = require('tiny-lru')
5
5
  const querystring = require('fast-querystring')
6
- const Stream = require('stream')
6
+ const fastContentTypeParse = require('fast-content-type-parse')
7
+ const Stream = require('node:stream')
7
8
  const buildRequest = require('./lib/request')
8
9
  const {
9
10
  filterPseudoHeaders,
@@ -29,8 +30,7 @@ const fastifyReplyFrom = fp(function from (fastify, opts, next) {
29
30
  ])
30
31
 
31
32
  const retryMethods = new Set(opts.retryMethods || [
32
- 'GET', 'HEAD', 'OPTIONS', 'TRACE'
33
- ])
33
+ 'GET', 'HEAD', 'OPTIONS', 'TRACE'])
34
34
 
35
35
  const cache = opts.disableCache ? undefined : lru(opts.cacheURLs || 100)
36
36
  const base = opts.base
@@ -60,6 +60,7 @@ const fastifyReplyFrom = fp(function from (fastify, opts, next) {
60
60
  const onError = opts.onError || onErrorDefault
61
61
  const retriesCount = opts.retriesCount || 0
62
62
  const maxRetriesOn503 = opts.maxRetriesOn503 || 10
63
+ const retryDelay = opts.retryDelay || undefined
63
64
 
64
65
  if (!source) {
65
66
  source = req.url
@@ -107,15 +108,13 @@ const fastifyReplyFrom = fp(function from (fastify, opts, next) {
107
108
  body = this.request.body
108
109
  } else {
109
110
  // Per RFC 7231 §3.1.1.5 if this header is not present we MAY assume application/octet-stream
110
- const contentType = req.headers['content-type'] || 'application/octet-stream'
111
- // detect if body should be encoded as JSON
112
- // supporting extended content-type header formats:
113
- // - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
114
- const lowerCaseContentType = contentType.toLowerCase()
115
- const plainContentType = lowerCaseContentType.indexOf(';') > -1
116
- ? lowerCaseContentType.slice(0, lowerCaseContentType.indexOf(';'))
117
- : lowerCaseContentType
118
- const shouldEncodeJSON = contentTypesToEncode.has(plainContentType)
111
+ let contentType = 'application/octet-stream'
112
+ if (req.headers['content-type']) {
113
+ const plainContentType = fastContentTypeParse.parse(req.headers['content-type'])
114
+ contentType = plainContentType.type
115
+ }
116
+
117
+ const shouldEncodeJSON = contentTypesToEncode.has(contentType)
119
118
  // transparently support JSON encoding
120
119
  body = shouldEncodeJSON ? JSON.stringify(this.request.body) : this.request.body
121
120
  // update origin request headers after encoding
@@ -142,10 +141,32 @@ const fastifyReplyFrom = fp(function from (fastify, opts, next) {
142
141
  const requestHeaders = rewriteRequestHeaders(this.request, headers)
143
142
  const contentLength = requestHeaders['content-length']
144
143
  let requestImpl
145
- if (retryMethods.has(method) && !contentLength) {
146
- requestImpl = createRequestRetry(request, this, retriesCount, retryOnError, maxRetriesOn503)
144
+
145
+ const getDefaultDelay = (req, res, err, retries) => {
146
+ if (retryMethods.has(method) && !contentLength) {
147
+ // Magic number, so why not 42? We might want to make this configurable.
148
+ let retryAfter = 42 * Math.random() * (retries + 1)
149
+
150
+ if (res && res.headers['retry-after']) {
151
+ retryAfter = res.headers['retry-after']
152
+ }
153
+ if (res && res.statusCode === 503 && req.method === 'GET') {
154
+ if (retriesCount === 0 && retries < maxRetriesOn503) {
155
+ return retryAfter
156
+ }
157
+ } else if (retriesCount > retries && err && err.code === retryOnError) {
158
+ return retryAfter
159
+ }
160
+ }
161
+ return null
162
+ }
163
+
164
+ if (retryDelay) {
165
+ requestImpl = createRequestRetry(request, this, (req, res, err, retries) => {
166
+ return retryDelay({ err, req, res, attempt: retries, getDefaultDelay })
167
+ })
147
168
  } else {
148
- requestImpl = request
169
+ requestImpl = createRequestRetry(request, this, getDefaultDelay)
149
170
  }
150
171
 
151
172
  requestImpl({ method, url, qs, headers: requestHeaders, body }, (err, res) => {
@@ -200,7 +221,6 @@ const fastifyReplyFrom = fp(function from (fastify, opts, next) {
200
221
  // actually destroy those sockets
201
222
  setImmediate(next)
202
223
  })
203
-
204
224
  next()
205
225
  }, {
206
226
  fastify: '4.x',
@@ -251,28 +271,15 @@ function isFastifyMultipartRegistered (fastify) {
251
271
  return (fastify.hasContentTypeParser('multipart') || fastify.hasContentTypeParser('multipart/form-data')) && fastify.hasRequestDecorator('multipart')
252
272
  }
253
273
 
254
- function createRequestRetry (requestImpl, reply, retriesCount, retryOnError, maxRetriesOn503) {
274
+ function createRequestRetry (requestImpl, reply, retryHandler) {
255
275
  function requestRetry (req, cb) {
256
276
  let retries = 0
257
277
 
258
278
  function run () {
259
279
  requestImpl(req, function (err, res) {
260
- // Magic number, so why not 42? We might want to make this configurable.
261
- let retryAfter = 42 * Math.random() * (retries + 1)
262
-
263
- if (res && res.headers['retry-after']) {
264
- retryAfter = res.headers['retry-after']
265
- }
266
- if (!reply.sent) {
267
- // always retry on 503 errors
268
- if (res && res.statusCode === 503 && req.method === 'GET') {
269
- if (retriesCount === 0 && retries < maxRetriesOn503) {
270
- // we should stop at some point
271
- return retry(retryAfter)
272
- }
273
- } else if (retriesCount > retries && err && err.code === retryOnError) {
274
- return retry(retryAfter)
275
- }
280
+ const retryDelay = retryHandler(req, res, err, retries)
281
+ if (!reply.sent && retryDelay) {
282
+ return retry(retryDelay)
276
283
  }
277
284
  cb(err, res)
278
285
  })
package/lib/request.js CHANGED
@@ -1,12 +1,12 @@
1
1
  'use strict'
2
- const http = require('http')
3
- const https = require('https')
4
- const querystring = require('querystring')
2
+ const http = require('node:http')
3
+ const https = require('node:https')
4
+ const querystring = require('node:querystring')
5
5
  const eos = require('end-of-stream')
6
6
  const pump = require('pump')
7
7
  const undici = require('undici')
8
8
  const { stripHttp1ConnectionHeaders } = require('./utils')
9
- const http2 = require('http2')
9
+ const http2 = require('node:http2')
10
10
 
11
11
  const {
12
12
  TimeoutError,
package/lib/utils.js CHANGED
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  function filterPseudoHeaders (headers) {
2
4
  const dest = {}
3
5
  const headersKeys = Object.keys(headers)
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@fastify/reply-from",
3
- "version": "9.4.0",
3
+ "version": "9.6.0",
4
4
  "description": "forward your HTTP request to another server, for fastify",
5
5
  "main": "index.js",
6
+ "type": "commonjs",
6
7
  "types": "types/index.d.ts",
7
8
  "scripts": {
8
9
  "lint": "standard | snazzy",
@@ -47,11 +48,12 @@
47
48
  "split2": "^4.1.0",
48
49
  "standard": "^17.0.0",
49
50
  "tap": "^16.2.0",
50
- "tsd": "^0.28.0"
51
+ "tsd": "^0.30.1"
51
52
  },
52
53
  "dependencies": {
53
54
  "@fastify/error": "^3.0.0",
54
55
  "end-of-stream": "^1.4.4",
56
+ "fast-content-type-parse": "^1.1.0",
55
57
  "fast-querystring": "^1.0.0",
56
58
  "fastify-plugin": "^4.0.0",
57
59
  "pump": "^3.0.0",
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const undici = require('undici')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
  const From = require('..')
9
9
 
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
  const split = require('split2')
9
9
 
@@ -1,12 +1,12 @@
1
1
  'use strict'
2
2
 
3
- const fs = require('fs')
4
- const path = require('path')
3
+ const fs = require('node:fs')
4
+ const path = require('node:path')
5
5
  const t = require('tap')
6
6
  const Fastify = require('fastify')
7
7
  const From = require('..')
8
8
  const Multipart = require('@fastify/multipart')
9
- const http = require('http')
9
+ const http = require('node:http')
10
10
  const get = require('simple-get').concat
11
11
  const FormData = require('form-data')
12
12
 
@@ -0,0 +1,47 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const fastify = require('fastify')
5
+ const get = require('simple-get').concat
6
+ const From = require('..')
7
+
8
+ const upstream = fastify()
9
+ t.teardown(upstream.close.bind(upstream))
10
+ t.plan(4)
11
+
12
+ upstream.post('/test', async (request, reply) => {
13
+ if (typeof request.body === 'object') {
14
+ return 'not ok'
15
+ }
16
+ return 'ok'
17
+ })
18
+
19
+ upstream.listen({ port: 0 }, function (err) {
20
+ t.error(err)
21
+
22
+ const app = fastify()
23
+ app.register(From)
24
+ t.teardown(app.close.bind(app))
25
+
26
+ app.post('/test', (request, reply) => {
27
+ if (request.body.method === 'invalid_method') {
28
+ return reply.code(400).send({ message: 'payload contains invalid method' })
29
+ }
30
+ reply.from(`http://127.0.0.1:${upstream.server.address().port}/test`)
31
+ })
32
+
33
+ app.listen({ port: 0 }, function (err) {
34
+ t.error(err)
35
+
36
+ get({
37
+ url: `http://127.0.0.1:${app.server.address().port}/test`,
38
+ headers: { 'content-type': 'application/json ; charset=utf-8' },
39
+ // eslint-disable-next-line no-useless-escape
40
+ body: '"{\\\"method\\\":\\\"invalid_method\\\"}"',
41
+ method: 'POST'
42
+ }, (err, res, data) => {
43
+ t.error(err)
44
+ t.equal(data.toString(), 'ok')
45
+ })
46
+ })
47
+ })
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,10 +3,10 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const https = require('https')
6
+ const https = require('node:https')
7
7
  const get = require('simple-get').concat
8
- const fs = require('fs')
9
- const path = require('path')
8
+ const fs = require('node:fs')
9
+ const path = require('node:path')
10
10
  const certs = {
11
11
  key: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.key')),
12
12
  cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.cert'))
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get')
8
8
 
9
9
  const instance = Fastify()
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,9 +3,9 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
- const querystring = require('querystring')
8
+ const querystring = require('node:querystring')
9
9
 
10
10
  const instance = Fastify()
11
11
 
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()
@@ -3,7 +3,7 @@
3
3
  const t = require('tap')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
- const http = require('http')
6
+ const http = require('node:http')
7
7
  const get = require('simple-get').concat
8
8
 
9
9
  const instance = Fastify()