Last active
July 15, 2025 21:04
-
-
Save Ethan-Arrowood/e03b163eaf58a1b847bf8e0aacb94cd6 to your computer and use it in GitHub Desktop.
A simplified example of Undici properly terminating connection when a FIN packet is forcibly sent
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { createServer } from 'node:http'; | |
| import { Client } from 'undici'; | |
| const server = createServer( | |
| { keepAlive: true, keepAliveTimeout: 20 * 1000 }, | |
| (req, res) => { | |
| res.writeHead(200, { | |
| 'Content-Type': 'text/plain', | |
| connection: 'keep-alive', | |
| 'keep-alive': 'timeout=20', | |
| }); | |
| // Send FIN packet randomly between 5 and 15 seconds | |
| setTimeout( | |
| () => { | |
| clearInterval(dataInternal); | |
| req.socket.end(() => { | |
| console.log('Socket closed after sending FIN'); | |
| }); | |
| }, | |
| Math.random() * (15000 - 5000) + 5000, | |
| ); | |
| // Write some data every second | |
| let c = 0; | |
| const dataInternal = setInterval(() => { | |
| res.write(`data ${c++}\n`); | |
| }, 1000); | |
| }, | |
| ); | |
| server.listen(0, () => { | |
| const client = new Client(`http://localhost:${server.address().port}`, { | |
| keepAliveTimeout: 20 * 1000, | |
| }); | |
| client.on('connect', () => { | |
| console.log('Client connected to server'); | |
| }); | |
| client.on('disconnect', () => { | |
| console.log('Client disconnected from server'); | |
| }); | |
| setTimeout(() => { | |
| console.log('20 (keep-alive) - 1 seconds has passed!'); | |
| console.log('client stats', client.stats); | |
| server.close(); | |
| }, 19 * 1000); | |
| client.request( | |
| { | |
| path: '/', | |
| method: 'GET', | |
| }, | |
| (error, response) => { | |
| console.log('client stats', client.stats); | |
| if (error) { | |
| console.error('Request failed:', error); | |
| return; | |
| } | |
| response.body.on('data', (chunk) => { | |
| console.log('Received chunk:', chunk.toString()); | |
| }); | |
| response.body.on('error', (err) => { | |
| console.error('Response body error:', err.message); | |
| }); | |
| response.body.on('end', () => { | |
| console.log('Response ended'); | |
| }); | |
| }, | |
| ); | |
| }); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example run: