Skip to content

Commit 63e3030

Browse files
net: fix bytesWritten during writev
When a writev is caused on a socket (sometimes through corking and uncorking), previously net would call Buffer.byteLength on the array of buffers and chunks, giving a completely erroneous byte length for the bulk of them (this is because byteLength is weird and coerces to strings). This commit fixes this bug by iterating over each chunk in the pending stack and calculating the length individually. Also adds a regression test.
1 parent 42a94e8 commit 63e3030

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

lib/net.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,18 @@ Socket.prototype.__defineGetter__('bytesWritten', function() {
742742
});
743743

744744
var buffer = this._pendingWrite;
745-
if (buffer) {
745+
if (Array.isArray(buffer)) {
746+
// was a writev, iterate over chunks to get total length
747+
for (let i = 0; i < buffer.length; i++) {
748+
let chunk = buffer[i];
749+
750+
if (chunk instanceof Buffer) {
751+
bytes += chunk.length;
752+
} else {
753+
bytes += Buffer.byteLength(chunk.data, chunk.encoding);
754+
}
755+
}
756+
} else if (buffer) {
746757
if (buffer.data instanceof Buffer) {
747758
bytes += buffer.data.length;
748759
} else {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const net = require('net');
6+
const Buffer = require('buffer').Buffer;
7+
8+
var server = net.createServer(function(socket) {
9+
socket.end();
10+
});
11+
12+
server.listen(common.PORT, common.mustCall(function() {
13+
var socket = net.connect(common.PORT);
14+
15+
// Cork the socket, then write twice; this should cause a writev, which
16+
// previously caused an err in the bytesWritten count.
17+
socket.cork();
18+
19+
socket.write('one');
20+
socket.write(new Buffer('twø', 'utf8'));
21+
22+
socket.uncork();
23+
24+
// one = 3 bytes, twø = 4 bytes
25+
assert.equal(socket.bytesWritten, 3 + 4);
26+
27+
socket.on('connect', common.mustCall(function() {
28+
assert.equal(socket.bytesWritten, 3 + 4);
29+
}));
30+
31+
socket.on('end', common.mustCall(function() {
32+
assert.equal(socket.bytesWritten, 3 + 4);
33+
34+
server.close();
35+
}));
36+
}));

0 commit comments

Comments
 (0)