index.js
1.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
var util = require('util')
var stream = require('readable-stream');
var RE_RES = /^(\d\d\d)\s.*/;
var RE_MULTI = /^(\d\d\d)-/;
// Codes from 100 to 200 are FTP marks
function isMark(code) {
code = parseInt(code, 10);
return code > 100 && code < 200;
}
module.exports = ResponseParser;
function ResponseParser() {
this.currentCode = 0;
this.buffer = [];
stream.Transform.call(this, {
objectMode: true
});
}
util.inherits(ResponseParser, stream.Transform);
ResponseParser.prototype._transform = function(chunk, encoding, done) {
var data = chunk.toString();
if (this._lastChunk) {
data = this._lastChunk + data;
this._lastChunk = '';
}
var lines = data.split(/\r?\n/);
// Check if last line contained a '\n' or was truncated, in which case we store
// it away to add it when a new write happens
if (lines && lines.length && lines[lines.length - 1] !== '') {
this._lastChunk = lines.pop();
}
lines = lines.filter(function(l) {
return !!l;
});
lines.forEach(function(line) {
var simpleRes = RE_RES.exec(line);
var multiRes;
if (simpleRes) {
var code = parseInt(simpleRes[1], 10);
if (this.buffer.length) {
this.buffer.push(line);
if (this.currentCode === code) {
line = this.buffer.join('\n');
this.buffer = [];
this.currentCode = 0;
}
}
this.push({
code: code,
text: line,
isMark: isMark(code),
// In FTP every response code above 399 means error in some way.
// Since the RFC is not respected by many servers, we are going to
// overgeneralize and consider every value above 399 as an error.
isError: code > 399
});
} else {
if (!this.buffer.length && (multiRes = RE_MULTI.exec(line))) {
this.currentCode = parseInt(multiRes[1], 10);
}
this.buffer.push(line.toString());
}
}, this);
done();
};