@fastify/reply-from 7.0.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.
- package/.github/dependabot.yml +13 -0
- package/.github/stale.yml +21 -0
- package/.github/workflows/ci.yml +60 -0
- package/.taprc +5 -0
- package/LICENSE +21 -0
- package/README.md +335 -0
- package/example.js +36 -0
- package/index.d.ts +99 -0
- package/index.js +262 -0
- package/lib/request.js +288 -0
- package/lib/utils.js +81 -0
- package/package.json +70 -0
- package/test/async-route-handler.js +50 -0
- package/test/base-get.js +48 -0
- package/test/base-path.js +38 -0
- package/test/base-querystring.js +48 -0
- package/test/build-url.js +69 -0
- package/test/core-with-path-in-base.js +50 -0
- package/test/custom-undici-instance.js +77 -0
- package/test/fastify-multipart-incompatibility.js +90 -0
- package/test/fixtures/fastify.cert +19 -0
- package/test/fixtures/fastify.key +27 -0
- package/test/fixtures/file.txt +1 -0
- package/test/full-get.js +45 -0
- package/test/full-https-get.js +55 -0
- package/test/full-post-extended-content-type.js +59 -0
- package/test/full-post-http2.js +49 -0
- package/test/full-post-stream-core.js +66 -0
- package/test/full-post-stream.js +64 -0
- package/test/full-post.js +56 -0
- package/test/full-querystring-rewrite-option-complex.js +48 -0
- package/test/full-querystring-rewrite-option-function.js +51 -0
- package/test/full-querystring-rewrite-option.js +48 -0
- package/test/full-querystring-rewrite-string.js +46 -0
- package/test/full-querystring-rewrite.js +46 -0
- package/test/full-querystring.js +46 -0
- package/test/full-rewrite-body-content-type.js +59 -0
- package/test/full-rewrite-body-http.js +63 -0
- package/test/full-rewrite-body-to-empty-string.js +61 -0
- package/test/full-rewrite-body-to-null.js +61 -0
- package/test/full-rewrite-body.js +61 -0
- package/test/get-upstream-http.js +70 -0
- package/test/get-upstream-undici.js +45 -0
- package/test/get-with-body.js +55 -0
- package/test/head-with-body.js +57 -0
- package/test/host-header.js +67 -0
- package/test/http-agents.js +55 -0
- package/test/http-http2.js +50 -0
- package/test/http-invalid-target.js +35 -0
- package/test/http-retry.js +109 -0
- package/test/http-timeout.js +56 -0
- package/test/http2-http2.js +57 -0
- package/test/http2-https.js +80 -0
- package/test/http2-invalid-target.js +36 -0
- package/test/http2-target-crash.js +53 -0
- package/test/http2-target-multi-crash.js +60 -0
- package/test/http2-timeout.js +92 -0
- package/test/https-agents.js +67 -0
- package/test/index.test-d.ts +136 -0
- package/test/modifyCoreObjects-false.js +48 -0
- package/test/no-body-opts-with-get.js +49 -0
- package/test/no-body-opts-with-head.js +51 -0
- package/test/no-stream-body-option.js +58 -0
- package/test/on-error.js +62 -0
- package/test/onResponse.js +48 -0
- package/test/padded-body.js +64 -0
- package/test/post-formbody.js +59 -0
- package/test/post-plain-text.js +56 -0
- package/test/post-with-custom-encoded-contenttype.js +65 -0
- package/test/retry-on-503.js +101 -0
- package/test/rewrite-headers.js +52 -0
- package/test/rewrite-request-headers.js +47 -0
- package/test/transform-body.js +61 -0
- package/test/undici-agent.js +77 -0
- package/test/undici-body.js +70 -0
- package/test/undici-options.js +73 -0
- package/test/undici-retry.js +109 -0
- package/test/undici-timeout-body-partial.js +60 -0
- package/test/undici-timeout-body.js +63 -0
- package/test/undici-timeout.js +61 -0
- package/test/undici-with-path-in-base.js +50 -0
- package/test/undici.js +50 -0
- package/test/unexpected-error.js +46 -0
- package/test/unix-http-undici-from.js +51 -0
- package/test/unix-http-undici.js +62 -0
- package/test/unix-http.js +65 -0
- package/test/unix-https-undici.js +71 -0
- package/test/unix-https.js +71 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Fastify = require('fastify')
|
|
4
|
+
const From = require('..')
|
|
5
|
+
const got = require('got')
|
|
6
|
+
const { test } = require('tap')
|
|
7
|
+
|
|
8
|
+
let retryNum = 1
|
|
9
|
+
|
|
10
|
+
const target = require('http').createServer(function (req, res) {
|
|
11
|
+
if (retryNum % 2 !== 0) {
|
|
12
|
+
req.socket.destroy()
|
|
13
|
+
} else {
|
|
14
|
+
res.statusCode = 200
|
|
15
|
+
res.setHeader('Content-Type', 'text/plain')
|
|
16
|
+
res.end('hello world')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
retryNum += 1
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('Will retry', async function (t) {
|
|
23
|
+
t.teardown(() => { retryNum = 1 })
|
|
24
|
+
|
|
25
|
+
await target.listen(0)
|
|
26
|
+
t.teardown(target.close.bind(target))
|
|
27
|
+
|
|
28
|
+
const instance = Fastify()
|
|
29
|
+
|
|
30
|
+
instance.register(From, { http: true })
|
|
31
|
+
|
|
32
|
+
instance.get('/', (request, reply) => {
|
|
33
|
+
reply.from(`http://localhost:${target.address().port}/`, {
|
|
34
|
+
retriesCount: 1,
|
|
35
|
+
onError: (reply, { error }) => {
|
|
36
|
+
t.equal(error.code, 'ECONNRESET')
|
|
37
|
+
reply.send(error)
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
await instance.listen(0)
|
|
43
|
+
t.teardown(instance.close.bind(instance))
|
|
44
|
+
|
|
45
|
+
const { statusCode } = await got.get(`http://localhost:${instance.server.address().port}/`, { retry: 0 })
|
|
46
|
+
t.equal(statusCode, 200)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('will not retry', async function (t) {
|
|
50
|
+
t.teardown(() => { retryNum = 1 })
|
|
51
|
+
|
|
52
|
+
await target.listen(0)
|
|
53
|
+
t.teardown(target.close.bind(target))
|
|
54
|
+
|
|
55
|
+
const instance = Fastify()
|
|
56
|
+
|
|
57
|
+
instance.register(From, { http: true })
|
|
58
|
+
|
|
59
|
+
instance.get('/', (request, reply) => {
|
|
60
|
+
reply.from(`http://localhost:${target.address().port}/`, {
|
|
61
|
+
retriesCount: 0,
|
|
62
|
+
onError: (reply, { error }) => {
|
|
63
|
+
t.equal(error.code, 'ECONNRESET')
|
|
64
|
+
reply.send(error)
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
await instance.listen(0)
|
|
70
|
+
t.teardown(instance.close.bind(instance))
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
await got.get(`http://localhost:${instance.server.address().port}/`, { retry: 0 })
|
|
74
|
+
t.fail()
|
|
75
|
+
} catch (err) {
|
|
76
|
+
t.equal(err.response.statusCode, 500)
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test('will not retry unsupported method', async function (t) {
|
|
81
|
+
t.teardown(() => { retryNum = 1 })
|
|
82
|
+
|
|
83
|
+
await target.listen(0)
|
|
84
|
+
t.teardown(target.close.bind(target))
|
|
85
|
+
|
|
86
|
+
const instance = Fastify()
|
|
87
|
+
|
|
88
|
+
instance.register(From, { http: true, retryMethods: ['DELETE'] })
|
|
89
|
+
|
|
90
|
+
instance.get('/', (request, reply) => {
|
|
91
|
+
reply.from(`http://localhost:${target.address().port}/`, {
|
|
92
|
+
retriesCount: 1,
|
|
93
|
+
onError: (reply, { error }) => {
|
|
94
|
+
t.equal(error.code, 'ECONNRESET')
|
|
95
|
+
reply.send(error)
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
await instance.listen(0)
|
|
101
|
+
t.teardown(instance.close.bind(instance))
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
await got.get(`http://localhost:${instance.server.address().port}/`, { retry: 0 })
|
|
105
|
+
t.fail()
|
|
106
|
+
} catch (err) {
|
|
107
|
+
t.equal(err.response.statusCode, 500)
|
|
108
|
+
}
|
|
109
|
+
})
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const t = require('tap')
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('..')
|
|
6
|
+
const got = require('got')
|
|
7
|
+
const FakeTimers = require('@sinonjs/fake-timers')
|
|
8
|
+
|
|
9
|
+
const clock = FakeTimers.createClock()
|
|
10
|
+
|
|
11
|
+
t.autoend(false)
|
|
12
|
+
|
|
13
|
+
const target = Fastify()
|
|
14
|
+
t.teardown(target.close.bind(target))
|
|
15
|
+
|
|
16
|
+
target.get('/', (request, reply) => {
|
|
17
|
+
t.pass('request arrives')
|
|
18
|
+
|
|
19
|
+
clock.setTimeout(() => {
|
|
20
|
+
reply.status(200).send('hello world')
|
|
21
|
+
t.end()
|
|
22
|
+
}, 200)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
async function main () {
|
|
26
|
+
await target.listen(0)
|
|
27
|
+
|
|
28
|
+
const instance = Fastify()
|
|
29
|
+
t.teardown(instance.close.bind(instance))
|
|
30
|
+
|
|
31
|
+
instance.register(From, { http: { requestOptions: { timeout: 100 } } })
|
|
32
|
+
|
|
33
|
+
instance.get('/', (request, reply) => {
|
|
34
|
+
reply.from(`http://localhost:${target.server.address().port}/`)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
await instance.listen(0)
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
await got.get(`http://localhost:${instance.server.address().port}/`, { retry: 0 })
|
|
41
|
+
} catch (err) {
|
|
42
|
+
t.equal(err.response.statusCode, 504)
|
|
43
|
+
t.match(err.response.headers['content-type'], /application\/json/)
|
|
44
|
+
t.same(JSON.parse(err.response.body), {
|
|
45
|
+
statusCode: 504,
|
|
46
|
+
error: 'Gateway Timeout',
|
|
47
|
+
message: 'Gateway Timeout'
|
|
48
|
+
})
|
|
49
|
+
clock.tick(200)
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
t.fail()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
main()
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const h2url = require('h2url')
|
|
4
|
+
const t = require('tap')
|
|
5
|
+
const Fastify = require('fastify')
|
|
6
|
+
const From = require('..')
|
|
7
|
+
const fs = require('fs')
|
|
8
|
+
const path = require('path')
|
|
9
|
+
const certs = {
|
|
10
|
+
key: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.key')),
|
|
11
|
+
cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.cert'))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
t.test('http2 -> http2', async (t) => {
|
|
15
|
+
const instance = Fastify({
|
|
16
|
+
http2: true,
|
|
17
|
+
https: certs
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
t.teardown(instance.close.bind(instance))
|
|
21
|
+
|
|
22
|
+
const target = Fastify({
|
|
23
|
+
http2: true
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
target.get('/', (request, reply) => {
|
|
27
|
+
t.pass('request proxied')
|
|
28
|
+
reply.code(404).header('x-my-header', 'hello!').send({
|
|
29
|
+
hello: 'world'
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
instance.get('/', (request, reply) => {
|
|
34
|
+
reply.from()
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
t.teardown(target.close.bind(target))
|
|
38
|
+
|
|
39
|
+
await target.listen(0)
|
|
40
|
+
|
|
41
|
+
instance.register(From, {
|
|
42
|
+
base: `http://localhost:${target.server.address().port}`,
|
|
43
|
+
http2: true,
|
|
44
|
+
rejectUnauthorized: false
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
await instance.listen(0)
|
|
48
|
+
|
|
49
|
+
const { headers, body } = await h2url.concat({
|
|
50
|
+
url: `https://localhost:${instance.server.address().port}`
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
t.equal(headers[':status'], 404)
|
|
54
|
+
t.equal(headers['x-my-header'], 'hello!')
|
|
55
|
+
t.match(headers['content-type'], /application\/json/)
|
|
56
|
+
t.same(JSON.parse(body), { hello: 'world' })
|
|
57
|
+
})
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const h2url = require('h2url')
|
|
4
|
+
const t = require('tap')
|
|
5
|
+
const Fastify = require('fastify')
|
|
6
|
+
const From = require('..')
|
|
7
|
+
const got = require('got')
|
|
8
|
+
const fs = require('fs')
|
|
9
|
+
const path = require('path')
|
|
10
|
+
const certs = {
|
|
11
|
+
allowHTTP1: true, // fallback support for HTTP1
|
|
12
|
+
key: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.key')),
|
|
13
|
+
cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.cert'))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const instance = Fastify({
|
|
17
|
+
http2: true,
|
|
18
|
+
https: certs
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
t.plan(4)
|
|
22
|
+
t.teardown(instance.close.bind(instance))
|
|
23
|
+
|
|
24
|
+
const target = Fastify({
|
|
25
|
+
https: certs
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
target.get('/', (request, reply) => {
|
|
29
|
+
t.pass('request proxied')
|
|
30
|
+
reply.code(404).header('x-my-header', 'hello!').send({
|
|
31
|
+
hello: 'world'
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
instance.get('/', (request, reply) => {
|
|
36
|
+
reply.from()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
t.teardown(target.close.bind(target))
|
|
40
|
+
|
|
41
|
+
async function run () {
|
|
42
|
+
await target.listen(0)
|
|
43
|
+
|
|
44
|
+
instance.register(From, {
|
|
45
|
+
base: `https://localhost:${target.server.address().port}`,
|
|
46
|
+
rejectUnauthorized: false
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
await instance.listen(0)
|
|
50
|
+
|
|
51
|
+
t.test('http2 -> https', async (t) => {
|
|
52
|
+
const { headers, body } = await h2url.concat({
|
|
53
|
+
url: `https://localhost:${instance.server.address().port}`
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
t.equal(headers[':status'], 404)
|
|
57
|
+
t.equal(headers['x-my-header'], 'hello!')
|
|
58
|
+
t.match(headers['content-type'], /application\/json/)
|
|
59
|
+
t.same(JSON.parse(body), { hello: 'world' })
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
t.test('https -> https', async (t) => {
|
|
63
|
+
try {
|
|
64
|
+
await got(`https://localhost:${instance.server.address().port}`, {
|
|
65
|
+
https: {
|
|
66
|
+
rejectUnauthorized: false
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
} catch (err) {
|
|
70
|
+
t.equal(err.response.statusCode, 404)
|
|
71
|
+
t.equal(err.response.headers['x-my-header'], 'hello!')
|
|
72
|
+
t.match(err.response.headers['content-type'], /application\/json/)
|
|
73
|
+
t.same(JSON.parse(err.response.body), { hello: 'world' })
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
t.fail()
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
run()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('..')
|
|
6
|
+
const got = require('got')
|
|
7
|
+
|
|
8
|
+
test('http2 invalid target', async (t) => {
|
|
9
|
+
const instance = Fastify()
|
|
10
|
+
|
|
11
|
+
t.teardown(instance.close.bind(instance))
|
|
12
|
+
|
|
13
|
+
instance.get('/', (request, reply) => {
|
|
14
|
+
reply.from()
|
|
15
|
+
})
|
|
16
|
+
instance.register(From, {
|
|
17
|
+
base: 'http://abc.xyz1',
|
|
18
|
+
http2: true
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
await instance.listen(0)
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
await got(`http://localhost:${instance.server.address().port}`)
|
|
25
|
+
} catch (err) {
|
|
26
|
+
t.equal(err.response.statusCode, 503)
|
|
27
|
+
t.match(err.response.headers['content-type'], /application\/json/)
|
|
28
|
+
t.same(JSON.parse(err.response.body), {
|
|
29
|
+
statusCode: 503,
|
|
30
|
+
error: 'Service Unavailable',
|
|
31
|
+
message: 'Service Unavailable'
|
|
32
|
+
})
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
t.fail()
|
|
36
|
+
})
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('..')
|
|
6
|
+
const got = require('got')
|
|
7
|
+
|
|
8
|
+
test('http -> http2 crash', async (t) => {
|
|
9
|
+
const instance = Fastify()
|
|
10
|
+
|
|
11
|
+
t.teardown(instance.close.bind(instance))
|
|
12
|
+
|
|
13
|
+
const target = Fastify({
|
|
14
|
+
http2: true
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
target.get('/', (request, reply) => {
|
|
18
|
+
t.pass('request proxied')
|
|
19
|
+
reply.code(200).send({
|
|
20
|
+
hello: 'world'
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
instance.get('/', (request, reply) => {
|
|
25
|
+
reply.from()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
t.teardown(target.close.bind(target))
|
|
29
|
+
|
|
30
|
+
await target.listen(0)
|
|
31
|
+
|
|
32
|
+
instance.register(From, {
|
|
33
|
+
base: `http://localhost:${target.server.address().port}`,
|
|
34
|
+
http2: true
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
await instance.listen(0)
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
await target.close()
|
|
41
|
+
await got(`http://localhost:${instance.server.address().port}`)
|
|
42
|
+
} catch (err) {
|
|
43
|
+
t.equal(err.response.statusCode, 503)
|
|
44
|
+
t.match(err.response.headers['content-type'], /application\/json/)
|
|
45
|
+
t.same(JSON.parse(err.response.body), {
|
|
46
|
+
statusCode: 503,
|
|
47
|
+
error: 'Service Unavailable',
|
|
48
|
+
message: 'Service Unavailable'
|
|
49
|
+
})
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
t.fail()
|
|
53
|
+
})
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('..')
|
|
6
|
+
const got = require('got')
|
|
7
|
+
|
|
8
|
+
test('http -> http2 crash multiple times', async (t) => {
|
|
9
|
+
const instance = Fastify()
|
|
10
|
+
|
|
11
|
+
t.teardown(instance.close.bind(instance))
|
|
12
|
+
|
|
13
|
+
instance.get('/', (request, reply) => {
|
|
14
|
+
reply.from()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
instance.register(From, {
|
|
18
|
+
base: 'http://localhost:3128',
|
|
19
|
+
http2: true,
|
|
20
|
+
sessionTimeout: 200
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
await instance.listen(0)
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
let target = setupTarget()
|
|
27
|
+
await target.listen(3128)
|
|
28
|
+
await got(`http://localhost:${instance.server.address().port}`)
|
|
29
|
+
await target.close()
|
|
30
|
+
target = setupTarget()
|
|
31
|
+
await target.listen(3128)
|
|
32
|
+
await got(`http://localhost:${instance.server.address().port}`)
|
|
33
|
+
await target.close()
|
|
34
|
+
await got(`http://localhost:${instance.server.address().port}`)
|
|
35
|
+
} catch (err) {
|
|
36
|
+
t.equal(err.response.statusCode, 503)
|
|
37
|
+
t.match(err.response.headers['content-type'], /application\/json/)
|
|
38
|
+
t.same(JSON.parse(err.response.body), {
|
|
39
|
+
statusCode: 503,
|
|
40
|
+
error: 'Service Unavailable',
|
|
41
|
+
message: 'Service Unavailable'
|
|
42
|
+
})
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
t.fail()
|
|
46
|
+
|
|
47
|
+
function setupTarget () {
|
|
48
|
+
const target = Fastify({
|
|
49
|
+
http2: true
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
target.get('/', (request, reply) => {
|
|
53
|
+
t.pass('request proxied')
|
|
54
|
+
reply.code(200).send({
|
|
55
|
+
hello: 'world'
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
return target
|
|
59
|
+
}
|
|
60
|
+
})
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('..')
|
|
6
|
+
const got = require('got')
|
|
7
|
+
|
|
8
|
+
test('http2 request timeout', async (t) => {
|
|
9
|
+
const target = Fastify({ http2: true, sessionTimeout: 0 })
|
|
10
|
+
t.teardown(target.close.bind(target))
|
|
11
|
+
|
|
12
|
+
target.get('/', () => {
|
|
13
|
+
t.pass('request arrives')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
await target.listen(0)
|
|
17
|
+
|
|
18
|
+
const instance = Fastify()
|
|
19
|
+
t.teardown(instance.close.bind(instance))
|
|
20
|
+
|
|
21
|
+
instance.register(From, {
|
|
22
|
+
base: `http://localhost:${target.server.address().port}`,
|
|
23
|
+
http2: { requestTimeout: 100 }
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
instance.get('/', (request, reply) => {
|
|
27
|
+
reply.from(`http://localhost:${target.server.address().port}/`)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
await instance.listen(0)
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
await got.get(`http://localhost:${instance.server.address().port}/`, {
|
|
34
|
+
retry: 0
|
|
35
|
+
})
|
|
36
|
+
} catch (err) {
|
|
37
|
+
t.equal(err.response.statusCode, 504)
|
|
38
|
+
t.match(err.response.headers['content-type'], /application\/json/)
|
|
39
|
+
t.same(JSON.parse(err.response.body), {
|
|
40
|
+
statusCode: 504,
|
|
41
|
+
error: 'Gateway Timeout',
|
|
42
|
+
message: 'Gateway Timeout'
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
t.fail()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
test('http2 session timeout', async (t) => {
|
|
52
|
+
const target = Fastify({ http2: true, sessionTimeout: 0 })
|
|
53
|
+
t.teardown(target.close.bind(target))
|
|
54
|
+
|
|
55
|
+
target.get('/', () => {
|
|
56
|
+
t.pass('request arrives')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
await target.listen(0)
|
|
60
|
+
|
|
61
|
+
const instance = Fastify()
|
|
62
|
+
t.teardown(instance.close.bind(instance))
|
|
63
|
+
|
|
64
|
+
instance.register(From, {
|
|
65
|
+
base: `http://localhost:${target.server.address().port}`,
|
|
66
|
+
http2: { sessionTimeout: 100 }
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
instance.get('/', (request, reply) => {
|
|
70
|
+
reply.from(`http://localhost:${target.server.address().port}/`)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
await instance.listen(0)
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
await got.get(`http://localhost:${instance.server.address().port}/`, {
|
|
77
|
+
retry: 0
|
|
78
|
+
})
|
|
79
|
+
} catch (err) {
|
|
80
|
+
t.equal(err.response.statusCode, 504)
|
|
81
|
+
t.match(err.response.headers['content-type'], /application\/json/)
|
|
82
|
+
t.same(JSON.parse(err.response.body), {
|
|
83
|
+
statusCode: 504,
|
|
84
|
+
error: 'Gateway Timeout',
|
|
85
|
+
message: 'Gateway Timeout'
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
t.fail()
|
|
92
|
+
})
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const t = require('tap')
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('..')
|
|
6
|
+
const http = require('http')
|
|
7
|
+
const https = require('https')
|
|
8
|
+
const get = require('simple-get').concat
|
|
9
|
+
|
|
10
|
+
const fs = require('fs')
|
|
11
|
+
const path = require('path')
|
|
12
|
+
const certs = {
|
|
13
|
+
key: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.key')),
|
|
14
|
+
cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.cert'))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const instance = Fastify({
|
|
18
|
+
https: certs
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
t.plan(10)
|
|
22
|
+
t.teardown(instance.close.bind(instance))
|
|
23
|
+
|
|
24
|
+
const target = https.createServer(certs, (req, res) => {
|
|
25
|
+
t.pass('request proxied')
|
|
26
|
+
t.equal(req.method, 'GET')
|
|
27
|
+
t.equal(req.url, '/')
|
|
28
|
+
res.statusCode = 205
|
|
29
|
+
res.setHeader('Content-Type', 'text/plain')
|
|
30
|
+
res.setHeader('x-my-header', 'hello!')
|
|
31
|
+
res.end('hello world')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
instance.get('/', (request, reply) => {
|
|
35
|
+
reply.from()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
t.teardown(target.close.bind(target))
|
|
39
|
+
|
|
40
|
+
target.listen(0, (err) => {
|
|
41
|
+
t.error(err)
|
|
42
|
+
|
|
43
|
+
instance.register(From, {
|
|
44
|
+
base: `https://localhost:${target.address().port}`,
|
|
45
|
+
http: {
|
|
46
|
+
agents: {
|
|
47
|
+
'http:': new http.Agent({}),
|
|
48
|
+
'https:': new https.Agent({})
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
instance.listen(0, (err) => {
|
|
54
|
+
t.error(err)
|
|
55
|
+
|
|
56
|
+
get({
|
|
57
|
+
url: `https://localhost:${instance.server.address().port}`,
|
|
58
|
+
rejectUnauthorized: false
|
|
59
|
+
}, (err, res, data) => {
|
|
60
|
+
t.error(err)
|
|
61
|
+
t.equal(res.headers['content-type'], 'text/plain')
|
|
62
|
+
t.equal(res.headers['x-my-header'], 'hello!')
|
|
63
|
+
t.equal(res.statusCode, 205)
|
|
64
|
+
t.equal(data.toString(), 'hello world')
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
})
|