11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../common');
31cb0ef41Sopenharmony_ciif (!common.hasCrypto)
41cb0ef41Sopenharmony_ci  common.skip('missing crypto');
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst tls = require('tls');
81cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciconst options = {
111cb0ef41Sopenharmony_ci  key: fixtures.readKey('agent2-key.pem'),
121cb0ef41Sopenharmony_ci  cert: fixtures.readKey('agent2-cert.pem')
131cb0ef41Sopenharmony_ci};
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciconst smallMessage = Buffer.from('hello world');
161cb0ef41Sopenharmony_ci// Used to test .pause(), so needs to be larger than the internal buffer
171cb0ef41Sopenharmony_ciconst largeMessage = Buffer.alloc(64 * 1024).fill('hello world');
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci// Test typical usage
201cb0ef41Sopenharmony_citls.createServer(options, common.mustCall(function(socket) {
211cb0ef41Sopenharmony_ci  this.close();
221cb0ef41Sopenharmony_ci  socket.end(smallMessage);
231cb0ef41Sopenharmony_ci})).listen(0, function() {
241cb0ef41Sopenharmony_ci  let received = 0;
251cb0ef41Sopenharmony_ci  const buffers = [];
261cb0ef41Sopenharmony_ci  const sockBuf = Buffer.alloc(8);
271cb0ef41Sopenharmony_ci  tls.connect({
281cb0ef41Sopenharmony_ci    port: this.address().port,
291cb0ef41Sopenharmony_ci    rejectUnauthorized: false,
301cb0ef41Sopenharmony_ci    onread: {
311cb0ef41Sopenharmony_ci      buffer: sockBuf,
321cb0ef41Sopenharmony_ci      callback: function(nread, buf) {
331cb0ef41Sopenharmony_ci        assert.strictEqual(buf, sockBuf);
341cb0ef41Sopenharmony_ci        received += nread;
351cb0ef41Sopenharmony_ci        buffers.push(Buffer.from(buf.slice(0, nread)));
361cb0ef41Sopenharmony_ci      }
371cb0ef41Sopenharmony_ci    }
381cb0ef41Sopenharmony_ci  }).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
391cb0ef41Sopenharmony_ci    assert.strictEqual(received, smallMessage.length);
401cb0ef41Sopenharmony_ci    assert.deepStrictEqual(Buffer.concat(buffers), smallMessage);
411cb0ef41Sopenharmony_ci  }));
421cb0ef41Sopenharmony_ci});
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci// Test Uint8Array support
451cb0ef41Sopenharmony_citls.createServer(options, common.mustCall(function(socket) {
461cb0ef41Sopenharmony_ci  this.close();
471cb0ef41Sopenharmony_ci  socket.end(smallMessage);
481cb0ef41Sopenharmony_ci})).listen(0, function() {
491cb0ef41Sopenharmony_ci  let received = 0;
501cb0ef41Sopenharmony_ci  let incoming = new Uint8Array(0);
511cb0ef41Sopenharmony_ci  const sockBuf = new Uint8Array(8);
521cb0ef41Sopenharmony_ci  tls.connect({
531cb0ef41Sopenharmony_ci    port: this.address().port,
541cb0ef41Sopenharmony_ci    rejectUnauthorized: false,
551cb0ef41Sopenharmony_ci    onread: {
561cb0ef41Sopenharmony_ci      buffer: sockBuf,
571cb0ef41Sopenharmony_ci      callback: function(nread, buf) {
581cb0ef41Sopenharmony_ci        assert.strictEqual(buf, sockBuf);
591cb0ef41Sopenharmony_ci        received += nread;
601cb0ef41Sopenharmony_ci        const newIncoming = new Uint8Array(incoming.length + nread);
611cb0ef41Sopenharmony_ci        newIncoming.set(incoming);
621cb0ef41Sopenharmony_ci        newIncoming.set(buf.slice(0, nread), incoming.length);
631cb0ef41Sopenharmony_ci        incoming = newIncoming;
641cb0ef41Sopenharmony_ci      }
651cb0ef41Sopenharmony_ci    }
661cb0ef41Sopenharmony_ci  }).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
671cb0ef41Sopenharmony_ci    assert.strictEqual(received, smallMessage.length);
681cb0ef41Sopenharmony_ci    assert.deepStrictEqual(incoming, new Uint8Array(smallMessage));
691cb0ef41Sopenharmony_ci  }));
701cb0ef41Sopenharmony_ci});
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci// Test Buffer callback usage
731cb0ef41Sopenharmony_citls.createServer(options, common.mustCall(function(socket) {
741cb0ef41Sopenharmony_ci  this.close();
751cb0ef41Sopenharmony_ci  socket.end(smallMessage);
761cb0ef41Sopenharmony_ci})).listen(0, function() {
771cb0ef41Sopenharmony_ci  let received = 0;
781cb0ef41Sopenharmony_ci  const incoming = [];
791cb0ef41Sopenharmony_ci  const bufPool = [ Buffer.alloc(2), Buffer.alloc(2), Buffer.alloc(2) ];
801cb0ef41Sopenharmony_ci  let bufPoolIdx = -1;
811cb0ef41Sopenharmony_ci  let bufPoolUsage = 0;
821cb0ef41Sopenharmony_ci  tls.connect({
831cb0ef41Sopenharmony_ci    port: this.address().port,
841cb0ef41Sopenharmony_ci    rejectUnauthorized: false,
851cb0ef41Sopenharmony_ci    onread: {
861cb0ef41Sopenharmony_ci      buffer: () => {
871cb0ef41Sopenharmony_ci        ++bufPoolUsage;
881cb0ef41Sopenharmony_ci        bufPoolIdx = (bufPoolIdx + 1) % bufPool.length;
891cb0ef41Sopenharmony_ci        return bufPool[bufPoolIdx];
901cb0ef41Sopenharmony_ci      },
911cb0ef41Sopenharmony_ci      callback: function(nread, buf) {
921cb0ef41Sopenharmony_ci        assert.strictEqual(buf, bufPool[bufPoolIdx]);
931cb0ef41Sopenharmony_ci        received += nread;
941cb0ef41Sopenharmony_ci        incoming.push(Buffer.from(buf.slice(0, nread)));
951cb0ef41Sopenharmony_ci      }
961cb0ef41Sopenharmony_ci    }
971cb0ef41Sopenharmony_ci  }).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
981cb0ef41Sopenharmony_ci    assert.strictEqual(received, smallMessage.length);
991cb0ef41Sopenharmony_ci    assert.deepStrictEqual(Buffer.concat(incoming), smallMessage);
1001cb0ef41Sopenharmony_ci    assert.strictEqual(bufPoolUsage, 7);
1011cb0ef41Sopenharmony_ci  }));
1021cb0ef41Sopenharmony_ci});
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci// Test Uint8Array callback support
1051cb0ef41Sopenharmony_citls.createServer(options, common.mustCall(function(socket) {
1061cb0ef41Sopenharmony_ci  this.close();
1071cb0ef41Sopenharmony_ci  socket.end(smallMessage);
1081cb0ef41Sopenharmony_ci})).listen(0, function() {
1091cb0ef41Sopenharmony_ci  let received = 0;
1101cb0ef41Sopenharmony_ci  let incoming = new Uint8Array(0);
1111cb0ef41Sopenharmony_ci  const bufPool = [ new Uint8Array(2), new Uint8Array(2), new Uint8Array(2) ];
1121cb0ef41Sopenharmony_ci  let bufPoolIdx = -1;
1131cb0ef41Sopenharmony_ci  let bufPoolUsage = 0;
1141cb0ef41Sopenharmony_ci  tls.connect({
1151cb0ef41Sopenharmony_ci    port: this.address().port,
1161cb0ef41Sopenharmony_ci    rejectUnauthorized: false,
1171cb0ef41Sopenharmony_ci    onread: {
1181cb0ef41Sopenharmony_ci      buffer: () => {
1191cb0ef41Sopenharmony_ci        ++bufPoolUsage;
1201cb0ef41Sopenharmony_ci        bufPoolIdx = (bufPoolIdx + 1) % bufPool.length;
1211cb0ef41Sopenharmony_ci        return bufPool[bufPoolIdx];
1221cb0ef41Sopenharmony_ci      },
1231cb0ef41Sopenharmony_ci      callback: function(nread, buf) {
1241cb0ef41Sopenharmony_ci        assert.strictEqual(buf, bufPool[bufPoolIdx]);
1251cb0ef41Sopenharmony_ci        received += nread;
1261cb0ef41Sopenharmony_ci        const newIncoming = new Uint8Array(incoming.length + nread);
1271cb0ef41Sopenharmony_ci        newIncoming.set(incoming);
1281cb0ef41Sopenharmony_ci        newIncoming.set(buf.slice(0, nread), incoming.length);
1291cb0ef41Sopenharmony_ci        incoming = newIncoming;
1301cb0ef41Sopenharmony_ci      }
1311cb0ef41Sopenharmony_ci    }
1321cb0ef41Sopenharmony_ci  }).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
1331cb0ef41Sopenharmony_ci    assert.strictEqual(received, smallMessage.length);
1341cb0ef41Sopenharmony_ci    assert.deepStrictEqual(incoming, new Uint8Array(smallMessage));
1351cb0ef41Sopenharmony_ci    assert.strictEqual(bufPoolUsage, 7);
1361cb0ef41Sopenharmony_ci  }));
1371cb0ef41Sopenharmony_ci});
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci// Test explicit socket pause
1401cb0ef41Sopenharmony_citls.createServer(options, common.mustCall(function(socket) {
1411cb0ef41Sopenharmony_ci  this.close();
1421cb0ef41Sopenharmony_ci  // Need larger message here to observe the pause
1431cb0ef41Sopenharmony_ci  socket.end(largeMessage);
1441cb0ef41Sopenharmony_ci})).listen(0, function() {
1451cb0ef41Sopenharmony_ci  let received = 0;
1461cb0ef41Sopenharmony_ci  const buffers = [];
1471cb0ef41Sopenharmony_ci  const sockBuf = Buffer.alloc(64);
1481cb0ef41Sopenharmony_ci  let pauseScheduled = false;
1491cb0ef41Sopenharmony_ci  const client = tls.connect({
1501cb0ef41Sopenharmony_ci    port: this.address().port,
1511cb0ef41Sopenharmony_ci    rejectUnauthorized: false,
1521cb0ef41Sopenharmony_ci    onread: {
1531cb0ef41Sopenharmony_ci      buffer: sockBuf,
1541cb0ef41Sopenharmony_ci      callback: function(nread, buf) {
1551cb0ef41Sopenharmony_ci        assert.strictEqual(buf, sockBuf);
1561cb0ef41Sopenharmony_ci        received += nread;
1571cb0ef41Sopenharmony_ci        buffers.push(Buffer.from(buf.slice(0, nread)));
1581cb0ef41Sopenharmony_ci        if (!pauseScheduled) {
1591cb0ef41Sopenharmony_ci          pauseScheduled = true;
1601cb0ef41Sopenharmony_ci          client.pause();
1611cb0ef41Sopenharmony_ci          setTimeout(() => {
1621cb0ef41Sopenharmony_ci            client.resume();
1631cb0ef41Sopenharmony_ci          }, 100);
1641cb0ef41Sopenharmony_ci        }
1651cb0ef41Sopenharmony_ci      }
1661cb0ef41Sopenharmony_ci    }
1671cb0ef41Sopenharmony_ci  }).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
1681cb0ef41Sopenharmony_ci    assert.strictEqual(received, largeMessage.length);
1691cb0ef41Sopenharmony_ci    assert.deepStrictEqual(Buffer.concat(buffers), largeMessage);
1701cb0ef41Sopenharmony_ci  }));
1711cb0ef41Sopenharmony_ci});
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci// Test implicit socket pause
1741cb0ef41Sopenharmony_citls.createServer(options, common.mustCall(function(socket) {
1751cb0ef41Sopenharmony_ci  this.close();
1761cb0ef41Sopenharmony_ci  // Need larger message here to observe the pause
1771cb0ef41Sopenharmony_ci  socket.end(largeMessage);
1781cb0ef41Sopenharmony_ci})).listen(0, function() {
1791cb0ef41Sopenharmony_ci  let received = 0;
1801cb0ef41Sopenharmony_ci  const buffers = [];
1811cb0ef41Sopenharmony_ci  const sockBuf = Buffer.alloc(64);
1821cb0ef41Sopenharmony_ci  let pauseScheduled = false;
1831cb0ef41Sopenharmony_ci  const client = tls.connect({
1841cb0ef41Sopenharmony_ci    port: this.address().port,
1851cb0ef41Sopenharmony_ci    rejectUnauthorized: false,
1861cb0ef41Sopenharmony_ci    onread: {
1871cb0ef41Sopenharmony_ci      buffer: sockBuf,
1881cb0ef41Sopenharmony_ci      callback: function(nread, buf) {
1891cb0ef41Sopenharmony_ci        assert.strictEqual(buf, sockBuf);
1901cb0ef41Sopenharmony_ci        received += nread;
1911cb0ef41Sopenharmony_ci        buffers.push(Buffer.from(buf.slice(0, nread)));
1921cb0ef41Sopenharmony_ci        if (!pauseScheduled) {
1931cb0ef41Sopenharmony_ci          pauseScheduled = true;
1941cb0ef41Sopenharmony_ci          setTimeout(() => {
1951cb0ef41Sopenharmony_ci            client.resume();
1961cb0ef41Sopenharmony_ci          }, 100);
1971cb0ef41Sopenharmony_ci          return false;
1981cb0ef41Sopenharmony_ci        }
1991cb0ef41Sopenharmony_ci        return true;
2001cb0ef41Sopenharmony_ci      }
2011cb0ef41Sopenharmony_ci    }
2021cb0ef41Sopenharmony_ci  }).on('data', common.mustNotCall()).on('end', common.mustCall(() => {
2031cb0ef41Sopenharmony_ci    assert.strictEqual(received, largeMessage.length);
2041cb0ef41Sopenharmony_ci    assert.deepStrictEqual(Buffer.concat(buffers), largeMessage);
2051cb0ef41Sopenharmony_ci  }));
2061cb0ef41Sopenharmony_ci});
207