1 | 'use strict'
|
2 |
|
3 | const net = require('net')
|
4 | const t = require('tap')
|
5 | const test = t.test
|
6 | const Fastify = require('..')
|
7 |
|
8 | test('close callback', t => {
|
9 | t.plan(4)
|
10 | const fastify = Fastify()
|
11 | fastify.addHook('onClose', onClose)
|
12 | function onClose (instance, done) {
|
13 | t.type(fastify, instance)
|
14 | done()
|
15 | }
|
16 |
|
17 | fastify.listen(0, err => {
|
18 | t.error(err)
|
19 |
|
20 | fastify.close((err) => {
|
21 | t.error(err)
|
22 | t.ok('close callback')
|
23 | })
|
24 | })
|
25 | })
|
26 |
|
27 | test('inside register', t => {
|
28 | t.plan(5)
|
29 | const fastify = Fastify()
|
30 | fastify.register(function (f, opts, next) {
|
31 | f.addHook('onClose', onClose)
|
32 | function onClose (instance, done) {
|
33 | t.ok(instance.prototype === fastify.prototype)
|
34 | t.strictEqual(instance, f)
|
35 | done()
|
36 | }
|
37 |
|
38 | next()
|
39 | })
|
40 |
|
41 | fastify.listen(0, err => {
|
42 | t.error(err)
|
43 |
|
44 | fastify.close((err) => {
|
45 | t.error(err)
|
46 | t.ok('close callback')
|
47 | })
|
48 | })
|
49 | })
|
50 |
|
51 | test('close order', t => {
|
52 | t.plan(5)
|
53 | const fastify = Fastify()
|
54 | const order = [1, 2, 3]
|
55 |
|
56 | fastify.register(function (f, opts, next) {
|
57 | f.addHook('onClose', (instance, done) => {
|
58 | t.is(order.shift(), 1)
|
59 | done()
|
60 | })
|
61 |
|
62 | next()
|
63 | })
|
64 |
|
65 | fastify.addHook('onClose', (instance, done) => {
|
66 | t.is(order.shift(), 2)
|
67 | done()
|
68 | })
|
69 |
|
70 | fastify.listen(0, err => {
|
71 | t.error(err)
|
72 |
|
73 | fastify.close((err) => {
|
74 | t.error(err)
|
75 | t.is(order.shift(), 3)
|
76 | })
|
77 | })
|
78 | })
|
79 |
|
80 | test('should not throw an error if the server is not listening', t => {
|
81 | t.plan(2)
|
82 | const fastify = Fastify()
|
83 | fastify.addHook('onClose', onClose)
|
84 | function onClose (instance, done) {
|
85 | t.type(fastify, instance)
|
86 | done()
|
87 | }
|
88 |
|
89 | fastify.close((err) => {
|
90 | t.error(err)
|
91 | })
|
92 | })
|
93 |
|
94 | test('onClose should keep the context', t => {
|
95 | t.plan(4)
|
96 | const fastify = Fastify()
|
97 | fastify.register(plugin)
|
98 |
|
99 | function plugin (instance, opts, next) {
|
100 | instance.decorate('test', true)
|
101 | instance.addHook('onClose', onClose)
|
102 | t.ok(instance.prototype === fastify.prototype)
|
103 |
|
104 | function onClose (i, done) {
|
105 | t.ok(i.test)
|
106 | t.strictEqual(i, instance)
|
107 | done()
|
108 | }
|
109 |
|
110 | next()
|
111 | }
|
112 |
|
113 | fastify.close((err) => {
|
114 | t.error(err)
|
115 | })
|
116 | })
|
117 |
|
118 | test('Should return error while closing - injection', t => {
|
119 | t.plan(4)
|
120 | const fastify = Fastify()
|
121 |
|
122 | fastify.addHook('onClose', (instance, done) => {
|
123 | setTimeout(done, 150)
|
124 | })
|
125 |
|
126 | fastify.get('/', (req, reply) => {
|
127 | reply.send({ hello: 'world' })
|
128 | })
|
129 |
|
130 | fastify.inject({
|
131 | method: 'GET',
|
132 | url: '/'
|
133 | }, (err, res) => {
|
134 | t.error(err)
|
135 | t.strictEqual(res.statusCode, 200)
|
136 | fastify.close()
|
137 |
|
138 | setTimeout(() => {
|
139 | fastify.inject({
|
140 | method: 'GET',
|
141 | url: '/'
|
142 | }, (err, res) => {
|
143 | t.ok(err)
|
144 | t.equal(err.message, 'Server is closed')
|
145 | })
|
146 | }, 100)
|
147 | })
|
148 | })
|
149 |
|
150 | t.test('Current opened connection should continue to work after closing and return "connection: close" header - return503OnClosing: false', t => {
|
151 | const fastify = Fastify({
|
152 | return503OnClosing: false
|
153 | })
|
154 |
|
155 | fastify.get('/', (req, reply) => {
|
156 | fastify.close()
|
157 | reply.send({ hello: 'world' })
|
158 | })
|
159 |
|
160 | fastify.listen(0, err => {
|
161 | t.error(err)
|
162 |
|
163 | const port = fastify.server.address().port
|
164 | const client = net.createConnection({ port: port }, () => {
|
165 | client.write('GET / HTTP/1.1\r\n\r\n')
|
166 |
|
167 | client.once('data', data => {
|
168 | t.match(data.toString(), /Connection:\s*keep-alive/i)
|
169 | t.match(data.toString(), /200 OK/i)
|
170 |
|
171 | client.write('GET / HTTP/1.1\r\n\r\n')
|
172 |
|
173 | client.once('data', data => {
|
174 | t.match(data.toString(), /Connection:\s*close/i)
|
175 | t.match(data.toString(), /200 OK/i)
|
176 |
|
177 |
|
178 | client.once('close', () => {
|
179 | t.end()
|
180 | })
|
181 | })
|
182 | })
|
183 | })
|
184 | })
|
185 | })
|
186 |
|
187 | t.test('Current opened connection should not accept new incoming connections', t => {
|
188 | const fastify = Fastify()
|
189 |
|
190 | fastify.get('/', (req, reply) => {
|
191 | fastify.close()
|
192 | reply.send({ hello: 'world' })
|
193 | })
|
194 |
|
195 | fastify.listen(0, err => {
|
196 | t.error(err)
|
197 |
|
198 | const port = fastify.server.address().port
|
199 | const client = net.createConnection({ port: port }, () => {
|
200 | client.write('GET / HTTP/1.1\r\n\r\n')
|
201 |
|
202 | const newConnection = net.createConnection({ port: port })
|
203 | newConnection.on('error', err => {
|
204 | t.ok(err)
|
205 | t.ok(['ECONNREFUSED', 'ECONNRESET'].includes(err.code))
|
206 |
|
207 | client.end()
|
208 | t.end()
|
209 | })
|
210 | })
|
211 | })
|
212 | })
|