Projekt

Obecné

Profil

Stáhnout (2.62 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
var once = require('once');
2
3
var noop = function() {};
4
5
var isRequest = function(stream) {
6
	return stream.setHeader && typeof stream.abort === 'function';
7
};
8
9
var isChildProcess = function(stream) {
10
	return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3
11
};
12
13
var eos = function(stream, opts, callback) {
14
	if (typeof opts === 'function') return eos(stream, null, opts);
15
	if (!opts) opts = {};
16
17
	callback = once(callback || noop);
18
19
	var ws = stream._writableState;
20
	var rs = stream._readableState;
21
	var readable = opts.readable || (opts.readable !== false && stream.readable);
22
	var writable = opts.writable || (opts.writable !== false && stream.writable);
23
	var cancelled = false;
24
25
	var onlegacyfinish = function() {
26
		if (!stream.writable) onfinish();
27
	};
28
29
	var onfinish = function() {
30
		writable = false;
31
		if (!readable) callback.call(stream);
32
	};
33
34
	var onend = function() {
35
		readable = false;
36
		if (!writable) callback.call(stream);
37
	};
38
39
	var onexit = function(exitCode) {
40
		callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null);
41
	};
42
43
	var onerror = function(err) {
44
		callback.call(stream, err);
45
	};
46
47
	var onclose = function() {
48
		process.nextTick(onclosenexttick);
49
	};
50
51
	var onclosenexttick = function() {
52
		if (cancelled) return;
53
		if (readable && !(rs && (rs.ended && !rs.destroyed))) return callback.call(stream, new Error('premature close'));
54
		if (writable && !(ws && (ws.ended && !ws.destroyed))) return callback.call(stream, new Error('premature close'));
55
	};
56
57
	var onrequest = function() {
58
		stream.req.on('finish', onfinish);
59
	};
60
61
	if (isRequest(stream)) {
62
		stream.on('complete', onfinish);
63
		stream.on('abort', onclose);
64
		if (stream.req) onrequest();
65
		else stream.on('request', onrequest);
66
	} else if (writable && !ws) { // legacy streams
67
		stream.on('end', onlegacyfinish);
68
		stream.on('close', onlegacyfinish);
69
	}
70
71
	if (isChildProcess(stream)) stream.on('exit', onexit);
72
73
	stream.on('end', onend);
74
	stream.on('finish', onfinish);
75
	if (opts.error !== false) stream.on('error', onerror);
76
	stream.on('close', onclose);
77
78
	return function() {
79
		cancelled = true;
80
		stream.removeListener('complete', onfinish);
81
		stream.removeListener('abort', onclose);
82
		stream.removeListener('request', onrequest);
83
		if (stream.req) stream.req.removeListener('finish', onfinish);
84
		stream.removeListener('end', onlegacyfinish);
85
		stream.removeListener('close', onlegacyfinish);
86
		stream.removeListener('finish', onfinish);
87
		stream.removeListener('exit', onexit);
88
		stream.removeListener('end', onend);
89
		stream.removeListener('error', onerror);
90
		stream.removeListener('close', onclose);
91
	};
92
};
93
94
module.exports = eos;