Skip to content

Commit 1b9263e

Browse files
authored
Merge pull request #198 from kiwiirc/xpaw/buffers
Use node buffers and decode full lines
2 parents d405f05 + 6047bff commit 1b9263e

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

src/transports/net.js

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
var net = require('net');
88
var tls = require('tls');
9-
var util = require('util');
109
var EventEmitter = require('events').EventEmitter;
1110
var Socks = require('socksjs');
1211
var iconv = require('iconv-lite');
@@ -27,7 +26,6 @@ module.exports = class Connection extends EventEmitter {
2726
this.socket_events = [];
2827

2928
this.encoding = 'utf8';
30-
this.incoming_buffer = '';
3129
}
3230

3331
isConnected() {
@@ -73,6 +71,7 @@ module.exports = class Connection extends EventEmitter {
7371

7472
this.disposeSocket();
7573
this.requested_disconnect = false;
74+
this.incoming_buffer = Buffer.from('');
7675

7776
// Include server name (SNI) if provided host is not an IP address
7877
if (!this.getAddressFamily(ircd_host)) {
@@ -164,17 +163,34 @@ module.exports = class Connection extends EventEmitter {
164163
}
165164

166165
onSocketData(data) {
167-
this.incoming_buffer += iconv.decode(data, this.encoding);
168-
169-
var lines = this.incoming_buffer.split('\n');
170-
if (lines[lines.length - 1] !== '') {
171-
this.incoming_buffer = lines.pop();
172-
} else {
173-
lines.pop();
174-
this.incoming_buffer = '';
175-
}
166+
// Buffer incoming data because multiple messages can arrive at once
167+
// without necessarily ending in a new line
168+
this.incoming_buffer = Buffer.concat(
169+
[this.incoming_buffer, data],
170+
this.incoming_buffer.length + data.length
171+
);
172+
173+
let startIndex = 0;
174+
175+
while (true) {
176+
// Search for the next new line in the buffered data
177+
const endIndex = this.incoming_buffer.indexOf(0x0A, startIndex) + 1;
178+
179+
// If this message is partial, keep it in the buffer until more data arrives.
180+
// If startIndex is equal to incoming_buffer.length, that means we reached the end
181+
// of the buffer and it ended on a new line, slice will return an empty buffer.
182+
if (endIndex === 0) {
183+
this.incoming_buffer = this.incoming_buffer.slice(startIndex);
184+
break;
185+
}
176186

177-
lines.forEach(line => this.emit('line', line));
187+
// Slice a single message delimited by a new line, decode it and emit it out
188+
let line = this.incoming_buffer.slice(startIndex, endIndex);
189+
line = iconv.decode(line, this.encoding);
190+
this.emit('line', line);
191+
192+
startIndex = endIndex;
193+
}
178194
}
179195

180196

0 commit comments

Comments
 (0)