node/test/parallel/test-tls-onread-static-buffer.js
Andrey Pechkurov 761c1b0797 tls: allow reading data into a static buffer
Refs: #25436

PR-URL: https://github.com/nodejs/node/pull/35753
Refs: https://github.com/nodejs/node/pull/25436
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
2020-10-28 16:07:29 +03:00

207 lines
6.2 KiB
JavaScript

'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const assert = require('assert');
const tls = require('tls');
const fixtures = require('../common/fixtures');
const options = {
key: fixtures.readKey('agent2-key.pem'),
cert: fixtures.readKey('agent2-cert.pem')
};
const smallMessage = Buffer.from('hello world');
// Used to test .pause(), so needs to be larger than the internal buffer
const largeMessage = Buffer.alloc(64 * 1024).fill('hello world');
// Test typical usage
tls.createServer(options, common.mustCall(function(socket) {
this.close();
socket.end(smallMessage);
})).listen(0, function() {
let received = 0;
const buffers = [];
const sockBuf = Buffer.alloc(8);
tls.connect({
port: this.address().port,
rejectUnauthorized: false,
onread: {
buffer: sockBuf,
callback: function(nread, buf) {
assert.strictEqual(buf, sockBuf);
received += nread;
buffers.push(Buffer.from(buf.slice(0, nread)));
}
}
}).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
assert.strictEqual(received, smallMessage.length);
assert.deepStrictEqual(Buffer.concat(buffers), smallMessage);
}));
});
// Test Uint8Array support
tls.createServer(options, common.mustCall(function(socket) {
this.close();
socket.end(smallMessage);
})).listen(0, function() {
let received = 0;
let incoming = new Uint8Array(0);
const sockBuf = new Uint8Array(8);
tls.connect({
port: this.address().port,
rejectUnauthorized: false,
onread: {
buffer: sockBuf,
callback: function(nread, buf) {
assert.strictEqual(buf, sockBuf);
received += nread;
const newIncoming = new Uint8Array(incoming.length + nread);
newIncoming.set(incoming);
newIncoming.set(buf.slice(0, nread), incoming.length);
incoming = newIncoming;
}
}
}).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
assert.strictEqual(received, smallMessage.length);
assert.deepStrictEqual(incoming, new Uint8Array(smallMessage));
}));
});
// Test Buffer callback usage
tls.createServer(options, common.mustCall(function(socket) {
this.close();
socket.end(smallMessage);
})).listen(0, function() {
let received = 0;
const incoming = [];
const bufPool = [ Buffer.alloc(2), Buffer.alloc(2), Buffer.alloc(2) ];
let bufPoolIdx = -1;
let bufPoolUsage = 0;
tls.connect({
port: this.address().port,
rejectUnauthorized: false,
onread: {
buffer: () => {
++bufPoolUsage;
bufPoolIdx = (bufPoolIdx + 1) % bufPool.length;
return bufPool[bufPoolIdx];
},
callback: function(nread, buf) {
assert.strictEqual(buf, bufPool[bufPoolIdx]);
received += nread;
incoming.push(Buffer.from(buf.slice(0, nread)));
}
}
}).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
assert.strictEqual(received, smallMessage.length);
assert.deepStrictEqual(Buffer.concat(incoming), smallMessage);
assert.strictEqual(bufPoolUsage, 7);
}));
});
// Test Uint8Array callback support
tls.createServer(options, common.mustCall(function(socket) {
this.close();
socket.end(smallMessage);
})).listen(0, function() {
let received = 0;
let incoming = new Uint8Array(0);
const bufPool = [ new Uint8Array(2), new Uint8Array(2), new Uint8Array(2) ];
let bufPoolIdx = -1;
let bufPoolUsage = 0;
tls.connect({
port: this.address().port,
rejectUnauthorized: false,
onread: {
buffer: () => {
++bufPoolUsage;
bufPoolIdx = (bufPoolIdx + 1) % bufPool.length;
return bufPool[bufPoolIdx];
},
callback: function(nread, buf) {
assert.strictEqual(buf, bufPool[bufPoolIdx]);
received += nread;
const newIncoming = new Uint8Array(incoming.length + nread);
newIncoming.set(incoming);
newIncoming.set(buf.slice(0, nread), incoming.length);
incoming = newIncoming;
}
}
}).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
assert.strictEqual(received, smallMessage.length);
assert.deepStrictEqual(incoming, new Uint8Array(smallMessage));
assert.strictEqual(bufPoolUsage, 7);
}));
});
// Test explicit socket pause
tls.createServer(options, common.mustCall(function(socket) {
this.close();
// Need larger message here to observe the pause
socket.end(largeMessage);
})).listen(0, function() {
let received = 0;
const buffers = [];
const sockBuf = Buffer.alloc(64);
let pauseScheduled = false;
const client = tls.connect({
port: this.address().port,
rejectUnauthorized: false,
onread: {
buffer: sockBuf,
callback: function(nread, buf) {
assert.strictEqual(buf, sockBuf);
received += nread;
buffers.push(Buffer.from(buf.slice(0, nread)));
if (!pauseScheduled) {
pauseScheduled = true;
client.pause();
setTimeout(() => {
client.resume();
}, 100);
}
}
}
}).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
assert.strictEqual(received, largeMessage.length);
assert.deepStrictEqual(Buffer.concat(buffers), largeMessage);
}));
});
// Test implicit socket pause
tls.createServer(options, common.mustCall(function(socket) {
this.close();
// Need larger message here to observe the pause
socket.end(largeMessage);
})).listen(0, function() {
let received = 0;
const buffers = [];
const sockBuf = Buffer.alloc(64);
let pauseScheduled = false;
const client = tls.connect({
port: this.address().port,
rejectUnauthorized: false,
onread: {
buffer: sockBuf,
callback: function(nread, buf) {
assert.strictEqual(buf, sockBuf);
received += nread;
buffers.push(Buffer.from(buf.slice(0, nread)));
if (!pauseScheduled) {
pauseScheduled = true;
setTimeout(() => {
client.resume();
}, 100);
return false;
}
return true;
}
}
}).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
assert.strictEqual(received, largeMessage.length);
assert.deepStrictEqual(Buffer.concat(buffers), largeMessage);
}));
});