1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- 'use strict'
- const https = require('https')
- module.exports = (server, grace) => {
- grace = typeof grace === 'undefined' ? Infinity : grace
- const reqsPerSocket = new Map()
- let stopped = false
- let gracefully = true
- if (server instanceof https.Server) {
- server.on('secureConnection', onConnection)
- } else {
- server.on('connection', onConnection)
- }
- server.on('request', onRequest)
- server.stop = stop
- server._pendingSockets = reqsPerSocket
- return server
- function onConnection (socket) {
- reqsPerSocket.set(socket, 0)
- socket.once('close', () => reqsPerSocket.delete(socket))
- }
- function onRequest (req, res) {
- reqsPerSocket.set(req.socket, reqsPerSocket.get(req.socket) + 1)
- res.once('finish', () => {
- const pending = reqsPerSocket.get(req.socket) - 1
- reqsPerSocket.set(req.socket, pending)
- if (stopped && pending === 0) {
- req.socket.end()
- }
- })
- }
- function stop (callback) {
- // allow request handlers to update state before we act on that state
- setImmediate(() => {
- stopped = true
- if (grace < Infinity) {
- setTimeout(destroyAll, grace).unref()
- }
- server.close(e => {
- if (callback) {
- callback(e, gracefully)
- }
- })
- reqsPerSocket.forEach(endIfIdle)
- })
- }
- function endIfIdle (requests, socket) {
- if (requests === 0) socket.end()
- }
- function destroyAll () {
- gracefully = false
- reqsPerSocket.forEach((reqs, socket) => socket.end())
- setImmediate(() => {
- reqsPerSocket.forEach((reqs, socket) => socket.destroy())
- })
- }
- }
|