Projekt

Obecné

Profil

Stáhnout (2.62 KB) Statistiky
| Větev: | Revize:
1
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;
(3-3/4)