@fastify/reply-from 12.0.2 → 12.2.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 (107) hide show
  1. package/.github/workflows/ci.yml +6 -0
  2. package/CLAUDE.md +66 -0
  3. package/LICENSE +4 -1
  4. package/README.md +24 -0
  5. package/index.js +12 -1
  6. package/lib/request.js +16 -6
  7. package/lib/utils.js +1 -0
  8. package/package.json +6 -8
  9. package/test/async-route-handler.test.js +29 -32
  10. package/test/balanced-pool.test.js +48 -0
  11. package/test/base-get.test.js +27 -30
  12. package/test/base-path.test.js +27 -24
  13. package/test/base-querystring.test.js +27 -30
  14. package/test/build-url.test.js +17 -15
  15. package/test/core-with-path-in-base.test.js +30 -33
  16. package/test/custom-undici-instance.test.js +28 -36
  17. package/test/disable-request-logging.test.js +38 -52
  18. package/test/fastify-multipart-incompatibility.test.js +43 -49
  19. package/test/fix-GHSA-v2v2-hph8-q5xp.test.js +3 -2
  20. package/test/full-delete-http2.test.js +12 -11
  21. package/test/full-get-test.test.js +27 -30
  22. package/test/full-https-get.test.js +30 -30
  23. package/test/full-post-extended-content-type.test.js +40 -44
  24. package/test/full-post-http2.test.js +18 -13
  25. package/test/full-post-stream-core.test.js +39 -43
  26. package/test/full-post-stream.test.js +39 -43
  27. package/test/full-post.test.js +36 -38
  28. package/test/full-querystring-rewrite-option-complex.test.js +27 -31
  29. package/test/full-querystring-rewrite-option-function-request.test.js +30 -36
  30. package/test/full-querystring-rewrite-option-function.test.js +30 -33
  31. package/test/full-querystring-rewrite-option.test.js +28 -31
  32. package/test/full-querystring-rewrite-string.test.js +27 -30
  33. package/test/full-querystring-rewrite.test.js +27 -30
  34. package/test/full-querystring.test.js +27 -30
  35. package/test/full-rewrite-body-content-type.test.js +37 -41
  36. package/test/full-rewrite-body-http.test.js +39 -43
  37. package/test/full-rewrite-body-to-empty-string.test.js +37 -41
  38. package/test/full-rewrite-body-to-null.test.js +37 -41
  39. package/test/full-rewrite-body.test.js +39 -43
  40. package/test/get-upstream-cache.test.js +12 -11
  41. package/test/get-upstream-http.test.js +35 -41
  42. package/test/get-upstream-type.test.js +24 -27
  43. package/test/get-upstream-undici.test.js +23 -26
  44. package/test/host-header.test.js +22 -18
  45. package/test/http-agents.test.js +27 -30
  46. package/test/http-global-agent.test.js +20 -33
  47. package/test/http-http2.test.js +13 -18
  48. package/test/http-invalid-target.test.js +13 -17
  49. package/test/http-retry.test.js +22 -29
  50. package/test/http-timeout.test.js +87 -27
  51. package/test/http2-canceled-streams-cleanup.test.js +117 -0
  52. package/test/http2-http2.test.js +8 -8
  53. package/test/http2-https.test.js +29 -27
  54. package/test/http2-invalid-base.test.js +2 -2
  55. package/test/http2-invalid-target.test.js +13 -17
  56. package/test/http2-target-crash.test.js +16 -20
  57. package/test/http2-target-multi-crash.test.js +22 -27
  58. package/test/http2-timeout-disabled.test.js +20 -15
  59. package/test/http2-timeout.test.js +94 -43
  60. package/test/http2-unix-socket.test.js +2 -2
  61. package/test/https-agents.test.js +31 -30
  62. package/test/https-global-agent.test.js +22 -31
  63. package/test/method.test.js +37 -42
  64. package/test/modifyCoreObjects-false.test.js +27 -30
  65. package/test/no-body-opts-with-get.test.js +25 -31
  66. package/test/no-body-opts-with-head.test.js +28 -32
  67. package/test/no-stream-body-option.test.js +34 -36
  68. package/test/on-error.test.js +21 -23
  69. package/test/on-invalid-upstream-response.test.js +30 -37
  70. package/test/onResponse.test.js +25 -32
  71. package/test/padded-body.test.js +38 -43
  72. package/test/post-formbody.test.js +35 -40
  73. package/test/post-plain-text.test.js +35 -39
  74. package/test/post-with-custom-encoded-contenttype.test.js +37 -39
  75. package/test/post-with-octet-stream.test.js +18 -88
  76. package/test/retry-on-503.test.js +27 -26
  77. package/test/retry-with-a-custom-handler.test.js +33 -40
  78. package/test/rewrite-headers-type.test.js +24 -29
  79. package/test/rewrite-headers.test.js +31 -36
  80. package/test/rewrite-request-headers-type.test.js +25 -28
  81. package/test/rewrite-request-headers.test.js +26 -30
  82. package/test/transform-body.test.js +37 -43
  83. package/test/undici-agent.test.js +27 -31
  84. package/test/undici-body.test.js +37 -42
  85. package/test/undici-chaining.test.js +35 -42
  86. package/test/undici-connect-timeout.test.js +13 -13
  87. package/test/undici-custom-dispatcher.test.js +11 -11
  88. package/test/undici-global-agent.test.js +14 -33
  89. package/test/undici-no-destroy.test.js +2 -2
  90. package/test/undici-options.test.js +21 -24
  91. package/test/undici-proxy-agent.test.js +4 -3
  92. package/test/undici-retry.test.js +24 -31
  93. package/test/undici-timeout-body-partial.test.js +14 -16
  94. package/test/undici-timeout-body.test.js +17 -19
  95. package/test/undici-timeout.test.js +86 -23
  96. package/test/undici-with-path-in-base.test.js +28 -31
  97. package/test/undici.test.js +28 -31
  98. package/test/unexpected-error.test.js +13 -18
  99. package/test/unix-http-undici-from.test.js +22 -31
  100. package/test/unix-http-undici.test.js +32 -40
  101. package/test/unix-http.test.js +31 -39
  102. package/test/unix-https-undici.test.js +30 -35
  103. package/test/unix-https.test.js +35 -40
  104. package/types/index.d.ts +13 -5
  105. package/types/index.test-d.ts +6 -6
  106. package/test/get-with-body.test.js +0 -55
  107. package/test/head-with-body.test.js +0 -57
@@ -1,17 +1,12 @@
1
1
  'use strict'
2
2
 
3
- const t = require('tap')
3
+ const t = require('node:test')
4
4
  const Fastify = require('fastify')
5
+ const { request } = require('undici')
5
6
  const From = require('..')
6
7
  const fs = require('node:fs')
7
8
  const querystring = require('node:querystring')
8
9
  const http = require('node:http')
9
- const get = require('simple-get').concat
10
-
11
- if (process.platform === 'win32') {
12
- t.pass()
13
- process.exit(0)
14
- }
15
10
 
16
11
  const socketPath = `${__filename}.socket`
17
12
  const upstream = `unix+http://${querystring.escape(socketPath)}/`
@@ -24,42 +19,39 @@ instance.register(From, {
24
19
  base: upstream
25
20
  })
26
21
 
27
- t.plan(10)
28
- t.teardown(instance.close.bind(instance))
29
-
30
- try {
31
- fs.unlinkSync(socketPath)
32
- } catch (_) {
33
- }
22
+ t.test('unix http', { skip: process.platform === 'win32' }, async (t) => {
23
+ t.plan(7)
24
+ t.after(() => instance.close())
25
+
26
+ try {
27
+ fs.unlinkSync(socketPath)
28
+ } catch (_) {
29
+ }
30
+
31
+ const target = http.createServer((req, res) => {
32
+ t.assert.ok('request proxied')
33
+ t.assert.strictEqual(req.method, 'GET')
34
+ t.assert.strictEqual(req.url, '/hello')
35
+ res.statusCode = 205
36
+ res.setHeader('Content-Type', 'text/plain')
37
+ res.setHeader('x-my-header', 'hello!')
38
+ res.end('hello world')
39
+ })
34
40
 
35
- const target = http.createServer((req, res) => {
36
- t.pass('request proxied')
37
- t.equal(req.method, 'GET')
38
- t.equal(req.url, '/hello')
39
- res.statusCode = 205
40
- res.setHeader('Content-Type', 'text/plain')
41
- res.setHeader('x-my-header', 'hello!')
42
- res.end('hello world')
43
- })
41
+ instance.get('/', (_request, reply) => {
42
+ reply.from('hello')
43
+ })
44
44
 
45
- instance.get('/', (_request, reply) => {
46
- reply.from('hello')
47
- })
45
+ t.after(() => target.close())
48
46
 
49
- t.teardown(target.close.bind(target))
47
+ await instance.listen({ port: 0 })
50
48
 
51
- instance.listen({ port: 0 }, (err) => {
52
- t.error(err)
49
+ await new Promise(resolve => target.listen(socketPath, resolve))
53
50
 
54
- target.listen(socketPath, (err) => {
55
- t.error(err)
51
+ const result = await request(`http://localhost:${instance.server.address().port}`)
56
52
 
57
- get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
58
- t.error(err)
59
- t.equal(res.headers['content-type'], 'text/plain')
60
- t.equal(res.headers['x-my-header'], 'hello!')
61
- t.equal(res.statusCode, 205)
62
- t.equal(data.toString(), 'hello world')
63
- })
64
- })
53
+ t.assert.strictEqual(result.headers['content-type'], 'text/plain')
54
+ t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
55
+ t.assert.strictEqual(result.statusCode, 205)
56
+ t.assert.strictEqual(await result.body.text(), 'hello world')
65
57
  })
@@ -1,11 +1,11 @@
1
1
  'use strict'
2
2
 
3
- const t = require('tap')
3
+ const t = require('node:test')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
6
  const https = require('node:https')
7
- const get = require('simple-get').concat
8
7
  const fs = require('node:fs')
8
+ const { request, Agent } = require('undici')
9
9
  const querystring = require('node:querystring')
10
10
  const path = require('node:path')
11
11
  const certs = {
@@ -13,11 +13,6 @@ const certs = {
13
13
  cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.cert'))
14
14
  }
15
15
 
16
- if (process.platform === 'win32') {
17
- t.pass()
18
- process.exit(0)
19
- }
20
-
21
16
  const socketPath = `${__filename}.socket`
22
17
 
23
18
  try {
@@ -32,40 +27,40 @@ instance.register(From, {
32
27
  base: `unix+https://${querystring.escape(socketPath)}`
33
28
  })
34
29
 
35
- t.plan(10)
36
- t.teardown(instance.close.bind(instance))
30
+ t.test('unix https undici', { skip: process.platform === 'win32' }, async (t) => {
31
+ t.plan(7)
32
+ t.after(() => instance.close())
37
33
 
38
- const target = https.createServer(certs, (req, res) => {
39
- t.pass('request proxied')
40
- t.equal(req.method, 'GET')
41
- t.equal(req.url, '/hello')
42
- res.statusCode = 205
43
- res.setHeader('Content-Type', 'text/plain')
44
- res.setHeader('x-my-header', 'hello!')
45
- res.end('hello world')
46
- })
34
+ const target = https.createServer(certs, (req, res) => {
35
+ t.assert.ok('request proxied')
36
+ t.assert.strictEqual(req.method, 'GET')
37
+ t.assert.strictEqual(req.url, '/hello')
38
+ res.statusCode = 205
39
+ res.setHeader('Content-Type', 'text/plain')
40
+ res.setHeader('x-my-header', 'hello!')
41
+ res.end('hello world')
42
+ })
47
43
 
48
- instance.get('/', (_request, reply) => {
49
- reply.from('hello')
50
- })
44
+ instance.get('/', (_request, reply) => {
45
+ reply.from('hello')
46
+ })
51
47
 
52
- t.teardown(target.close.bind(target))
48
+ t.after(() => target.close())
53
49
 
54
- instance.listen({ port: 0 }, (err) => {
55
- t.error(err)
50
+ await instance.listen({ port: 0 })
56
51
 
57
- target.listen(socketPath, (err) => {
58
- t.error(err)
52
+ await new Promise(resolve => target.listen(socketPath, resolve))
59
53
 
60
- get({
61
- url: `https://localhost:${instance.server.address().port}`,
62
- rejectUnauthorized: false
63
- }, (err, res, data) => {
64
- t.error(err)
65
- t.equal(res.headers['content-type'], 'text/plain')
66
- t.equal(res.headers['x-my-header'], 'hello!')
67
- t.equal(res.statusCode, 205)
68
- t.equal(data.toString(), 'hello world')
54
+ const result = await request(`https://localhost:${instance.server.address().port}`, {
55
+ dispatcher: new Agent({
56
+ connect: {
57
+ rejectUnauthorized: false
58
+ }
69
59
  })
70
60
  })
61
+
62
+ t.assert.strictEqual(result.headers['content-type'], 'text/plain')
63
+ t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
64
+ t.assert.strictEqual(result.statusCode, 205)
65
+ t.assert.strictEqual(await result.body.text(), 'hello world')
71
66
  })
@@ -1,10 +1,10 @@
1
1
  'use strict'
2
2
 
3
- const t = require('tap')
3
+ const t = require('node:test')
4
4
  const Fastify = require('fastify')
5
5
  const From = require('..')
6
6
  const https = require('node:https')
7
- const get = require('simple-get').concat
7
+ const { request, Agent } = require('undici')
8
8
  const fs = require('node:fs')
9
9
  const querystring = require('node:querystring')
10
10
  const path = require('node:path')
@@ -13,11 +13,6 @@ const certs = {
13
13
  cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.cert'))
14
14
  }
15
15
 
16
- if (process.platform === 'win32') {
17
- t.pass()
18
- process.exit(0)
19
- }
20
-
21
16
  const instance = Fastify({
22
17
  https: certs
23
18
  })
@@ -25,47 +20,47 @@ instance.register(From, {
25
20
  http: true
26
21
  })
27
22
 
28
- t.plan(10)
29
- t.teardown(instance.close.bind(instance))
23
+ t.test('unix https', { skip: process.platform === 'win32' }, async (t) => {
24
+ t.plan(7)
25
+ t.after(() => instance.close())
30
26
 
31
- const socketPath = `${__filename}.socket`
27
+ const socketPath = `${__filename}.socket`
32
28
 
33
- try {
34
- fs.unlinkSync(socketPath)
35
- } catch (_) {
36
- }
29
+ try {
30
+ fs.unlinkSync(socketPath)
31
+ } catch (_) {
32
+ }
37
33
 
38
- const target = https.createServer(certs, (req, res) => {
39
- t.pass('request proxied')
40
- t.equal(req.method, 'GET')
41
- t.equal(req.url, '/hello')
42
- res.statusCode = 205
43
- res.setHeader('Content-Type', 'text/plain')
44
- res.setHeader('x-my-header', 'hello!')
45
- res.end('hello world')
46
- })
34
+ const target = https.createServer(certs, (req, res) => {
35
+ t.assert.ok('request proxied')
36
+ t.assert.strictEqual(req.method, 'GET')
37
+ t.assert.strictEqual(req.url, '/hello')
38
+ res.statusCode = 205
39
+ res.setHeader('Content-Type', 'text/plain')
40
+ res.setHeader('x-my-header', 'hello!')
41
+ res.end('hello world')
42
+ })
47
43
 
48
- instance.get('/', (_request, reply) => {
49
- reply.from(`unix+https://${querystring.escape(socketPath)}/hello`)
50
- })
44
+ instance.get('/', (_request, reply) => {
45
+ reply.from(`unix+https://${querystring.escape(socketPath)}/hello`)
46
+ })
51
47
 
52
- t.teardown(target.close.bind(target))
48
+ t.after(() => target.close())
53
49
 
54
- instance.listen({ port: 0 }, (err) => {
55
- t.error(err)
50
+ await instance.listen({ port: 0 })
56
51
 
57
- target.listen(socketPath, (err) => {
58
- t.error(err)
52
+ await new Promise(resolve => target.listen(socketPath, resolve))
59
53
 
60
- get({
61
- url: `https://localhost:${instance.server.address().port}`,
62
- rejectUnauthorized: false
63
- }, (err, res, data) => {
64
- t.error(err)
65
- t.equal(res.headers['content-type'], 'text/plain')
66
- t.equal(res.headers['x-my-header'], 'hello!')
67
- t.equal(res.statusCode, 205)
68
- t.equal(data.toString(), 'hello world')
54
+ const result = await request(`https://localhost:${instance.server.address().port}`, {
55
+ dispatcher: new Agent({
56
+ connect: {
57
+ rejectUnauthorized: false
58
+ }
69
59
  })
70
60
  })
61
+
62
+ t.assert.strictEqual(result.headers['content-type'], 'text/plain')
63
+ t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
64
+ t.assert.strictEqual(result.statusCode, 205)
65
+ t.assert.strictEqual(await result.body.text(), 'hello world')
71
66
  })
package/types/index.d.ts CHANGED
@@ -15,19 +15,20 @@ import {
15
15
  Agent,
16
16
  AgentOptions,
17
17
  IncomingHttpHeaders,
18
+ IncomingMessage,
18
19
  RequestOptions,
19
- } from 'http'
20
+ } from 'node:http'
20
21
  import {
21
22
  ClientSessionOptions,
22
23
  ClientSessionRequestOptions,
23
24
  IncomingHttpHeaders as Http2IncomingHttpHeaders,
24
25
  SecureClientSessionOptions,
25
- } from 'http2'
26
+ } from 'node:http2'
26
27
  import {
27
28
  Agent as SecureAgent,
28
29
  AgentOptions as SecureAgentOptions,
29
30
  RequestOptions as SecureRequestOptions
30
- } from 'https'
31
+ } from 'node:https'
31
32
  import { Pool, ProxyAgent, Dispatcher } from 'undici'
32
33
 
33
34
  declare module 'fastify' {
@@ -55,6 +56,11 @@ declare namespace fastifyReplyFrom {
55
56
  retriesCount: number;
56
57
  getDefaultDelay: () => number | null;
57
58
  }
59
+
60
+ export type RawServerResponse<T extends RawServerBase> = RawReplyDefaultExpression<T> & {
61
+ stream: IncomingMessage
62
+ }
63
+
58
64
  export interface FastifyReplyFromHooks {
59
65
  queryString?: { [key: string]: unknown } | QueryStringFunction;
60
66
  contentType?: string;
@@ -63,7 +69,7 @@ declare namespace fastifyReplyFrom {
63
69
  onResponse?: (
64
70
  request: FastifyRequest<RequestGenericInterface, RawServerBase>,
65
71
  reply: FastifyReply<RouteGenericInterface, RawServerBase>,
66
- res: RawReplyDefaultExpression<RawServerBase>
72
+ res: RawServerResponse<RawServerBase>
67
73
  ) => void;
68
74
  onError?: (
69
75
  reply: FastifyReply<RouteGenericInterface, RawServerBase>,
@@ -83,6 +89,7 @@ declare namespace fastifyReplyFrom {
83
89
  base: string
84
90
  ) => string;
85
91
  method?: HTTPMethods;
92
+ timeout?: number;
86
93
  }
87
94
 
88
95
  interface Http2Options {
@@ -99,12 +106,13 @@ declare namespace fastifyReplyFrom {
99
106
  }
100
107
 
101
108
  export interface FastifyReplyFromOptions {
102
- base?: string;
109
+ base?: string | string[];
103
110
  cacheURLs?: number;
104
111
  disableCache?: boolean;
105
112
  http?: HttpOptions;
106
113
  http2?: Http2Options | boolean;
107
114
  undici?: Pool.Options & { proxy?: string | URL | ProxyAgent.Options } | { request: Dispatcher['request'] };
115
+ balancedPoolOptions?: Pool.Options & Record<string, unknown>;
108
116
  contentTypesToEncode?: string[];
109
117
  retryMethods?: (HTTPMethods | 'TRACE')[];
110
118
  maxRetriesOn503?: number;
@@ -1,11 +1,11 @@
1
- import fastify, { FastifyReply, FastifyRequest, RawReplyDefaultExpression, RawServerBase, RequestGenericInterface, RouteGenericInterface } from 'fastify'
1
+ import fastify, { FastifyReply, FastifyRequest, RawServerBase, RequestGenericInterface, RouteGenericInterface } from 'fastify'
2
2
  import * as http from 'node:http'
3
- import { IncomingHttpHeaders } from 'http2'
3
+ import { IncomingHttpHeaders } from 'node:http2'
4
4
  import * as https from 'node:https'
5
- import { AddressInfo } from 'net'
5
+ import { AddressInfo } from 'node:net'
6
6
  import { expectType } from 'tsd'
7
7
  import { Agent, Client, Dispatcher, Pool } from 'undici'
8
- import replyFrom, { FastifyReplyFromOptions } from '..'
8
+ import replyFrom, { FastifyReplyFromOptions, RawServerResponse } from '..'
9
9
  // @ts-ignore
10
10
  import tap from 'tap'
11
11
 
@@ -70,6 +70,7 @@ async function main () {
70
70
  })
71
71
  server.get('/v3', (_request, reply) => {
72
72
  reply.from('/v3', {
73
+ timeout: 1000,
73
74
  body: { hello: 'world' },
74
75
  rewriteRequestHeaders (req, headers) {
75
76
  expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(req)
@@ -82,7 +83,7 @@ async function main () {
82
83
  onResponse (request, reply, res) {
83
84
  expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(request)
84
85
  expectType<FastifyReply<RouteGenericInterface, RawServerBase>>(reply)
85
- expectType<RawReplyDefaultExpression<RawServerBase>>(res)
86
+ expectType<RawServerResponse<RawServerBase>>(res)
86
87
  expectType<number>(res.statusCode)
87
88
  }
88
89
  })
@@ -102,7 +103,6 @@ async function main () {
102
103
  instance.get('/http2', (_request, reply) => {
103
104
  reply.from('/', {
104
105
  method: 'POST',
105
- // eslint-disable-next-line n/handle-callback-err -- Not a real request, not handling errors
106
106
  retryDelay: ({ req, res, getDefaultDelay }) => {
107
107
  const defaultDelay = getDefaultDelay()
108
108
  if (defaultDelay) return defaultDelay
@@ -1,55 +0,0 @@
1
- 'use strict'
2
-
3
- const t = require('tap')
4
- const Fastify = require('fastify')
5
- const From = require('..')
6
- const http = require('node:http')
7
- const get = require('simple-get').concat
8
-
9
- const instance = Fastify()
10
-
11
- t.plan(11)
12
- t.teardown(instance.close.bind(instance))
13
-
14
- const target = http.createServer((req, res) => {
15
- t.pass('request proxied')
16
- t.equal(req.method, 'GET')
17
- t.equal(req.url, '/')
18
- t.equal(req.body, undefined)
19
- res.statusCode = 205
20
- res.setHeader('Content-Type', 'text/plain')
21
- res.setHeader('x-my-header', 'hello!')
22
- res.end('hello world')
23
- })
24
-
25
- instance.get('/', (_request, reply) => {
26
- reply.from()
27
- })
28
-
29
- t.teardown(target.close.bind(target))
30
-
31
- target.listen({ port: 0 }, (err) => {
32
- t.error(err)
33
-
34
- instance.register(From, {
35
- base: `http://localhost:${target.address().port}`,
36
- // Use node core HTTP, Undici requires spec compliance
37
- http: {}
38
- })
39
-
40
- instance.listen({ port: 0 }, (err) => {
41
- t.error(err)
42
-
43
- get({
44
- url: `http://localhost:${instance.server.address().port}`,
45
- method: 'GET',
46
- body: 'this is get body'
47
- }, (err, res, data) => {
48
- t.error(err)
49
- t.equal(res.headers['content-type'], 'text/plain')
50
- t.equal(res.headers['x-my-header'], 'hello!')
51
- t.equal(res.statusCode, 205)
52
- t.equal(data.toString(), 'hello world')
53
- })
54
- })
55
- })
@@ -1,57 +0,0 @@
1
- 'use strict'
2
-
3
- const t = require('tap')
4
- const Fastify = require('fastify')
5
- const From = require('..')
6
- const http = require('node:http')
7
- const get = require('simple-get').concat
8
-
9
- const instance = Fastify()
10
-
11
- t.plan(13)
12
- t.teardown(instance.close.bind(instance))
13
-
14
- const target = http.createServer((req, res) => {
15
- t.pass('request proxied')
16
- t.equal(req.method, 'HEAD')
17
- t.equal(req.url, '/')
18
- t.equal(req.headers['content-length'], '16')
19
- t.equal(req.body, undefined)
20
- res.statusCode = 205
21
- res.setHeader('Content-Type', 'text/plain')
22
- res.setHeader('x-my-header', 'hello!')
23
- res.end('hello world')
24
- })
25
-
26
- instance.head('/', (_request, reply) => {
27
- t.pass('head received')
28
- reply.from()
29
- })
30
-
31
- t.teardown(target.close.bind(target))
32
-
33
- target.listen({ port: 0 }, (err) => {
34
- t.error(err)
35
-
36
- instance.register(From, {
37
- base: `http://localhost:${target.address().port}`,
38
- // Use node core HTTP, Undici requires spec compliance
39
- http: {}
40
- })
41
-
42
- instance.listen({ port: 0 }, (err) => {
43
- t.error(err)
44
-
45
- get({
46
- url: `http://localhost:${instance.server.address().port}`,
47
- method: 'HEAD',
48
- body: 'this is get body'
49
- }, (err, res, data) => {
50
- t.error(err)
51
- t.equal(res.headers['content-type'], 'text/plain')
52
- t.equal(res.headers['x-my-header'], 'hello!')
53
- t.equal(res.statusCode, 205)
54
- t.equal(data.toString(), '')
55
- })
56
- })
57
- })