123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- 'use strict'
- module.exports = onFinished
- module.exports.isFinished = isFinished
- var first = require('ee-first')
- var defer = typeof setImmediate === 'function'
- ? setImmediate
- : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
- function onFinished(msg, listener) {
- if (isFinished(msg) !== false) {
- defer(listener, null, msg)
- return msg
- }
-
- attachListener(msg, listener)
- return msg
- }
- function isFinished(msg) {
- var socket = msg.socket
- if (typeof msg.finished === 'boolean') {
-
- return Boolean(msg.finished || (socket && !socket.writable))
- }
- if (typeof msg.complete === 'boolean') {
-
- return Boolean(msg.upgrade || !socket || !socket.readable || (msg.complete && !msg.readable))
- }
-
- return undefined
- }
- function attachFinishedListener(msg, callback) {
- var eeMsg
- var eeSocket
- var finished = false
- function onFinish(error) {
- eeMsg.cancel()
- eeSocket.cancel()
- finished = true
- callback(error)
- }
-
- eeMsg = eeSocket = first([[msg, 'end', 'finish']], onFinish)
- function onSocket(socket) {
-
- msg.removeListener('socket', onSocket)
- if (finished) return
- if (eeMsg !== eeSocket) return
-
- eeSocket = first([[socket, 'error', 'close']], onFinish)
- }
- if (msg.socket) {
-
- onSocket(msg.socket)
- return
- }
-
- msg.on('socket', onSocket)
- if (msg.socket === undefined) {
-
- patchAssignSocket(msg, onSocket)
- }
- }
- function attachListener(msg, listener) {
- var attached = msg.__onFinished
-
- if (!attached || !attached.queue) {
- attached = msg.__onFinished = createListener(msg)
- attachFinishedListener(msg, attached)
- }
- attached.queue.push(listener)
- }
- function createListener(msg) {
- function listener(err) {
- if (msg.__onFinished === listener) msg.__onFinished = null
- if (!listener.queue) return
- var queue = listener.queue
- listener.queue = null
- for (var i = 0; i < queue.length; i++) {
- queue[i](err, msg)
- }
- }
- listener.queue = []
- return listener
- }
- function patchAssignSocket(res, callback) {
- var assignSocket = res.assignSocket
- if (typeof assignSocket !== 'function') return
-
- res.assignSocket = function _assignSocket(socket) {
- assignSocket.call(this, socket)
- callback(socket)
- }
- }
|