/*eslint no-console: 0 */ 'use strict'; let net = require('net'); let tls = require('tls'); module.exports = runClientMockup; function runClientMockup(options, callback) { options = options || {}; let host = options.host || 'localhost'; let port = options.port || 25; let commands = [].concat(options.commands || []); let debug = options.debug; let ignore_data = false; let responses = []; let command = ''; let callbackSent = false; let delay; let socket = (options.secure ? tls : net).connect({ rejectUnauthorized: false, port, host }, () => { socket.on('close', () => { if (callbackSent) { return; } callbackSent = true; if (typeof callback === 'function') { return callback(Buffer.concat(responses)); } }); let onData = function (chunk) { if (ignore_data) { return; } responses.push(chunk); if (debug) { console.log('S: ' + chunk.toString('binary').trim()); } if (!commands.length) { return; } if (typeof command === 'string' && command.match(/^[a-z0-9]+ STARTTLS$/i)) { // wait until server sends response to the STARTTLS command if (!/STARTTLS completed/.test(Buffer.concat(responses).toString())) { return; } ignore_data = true; if (debug) { console.log('Initiated TLS connection'); } socket.removeAllListeners('data'); let secureSocket = tls.connect({ rejectUnauthorized: false, socket, host }, () => { ignore_data = false; socket = secureSocket; if (debug) { console.log('TLS connection secured'); } secureSocket.on('data', onData); secureSocket.on('close', () => { if (callbackSent) { return; } callbackSent = true; if (typeof callback === 'function') { return callback(Buffer.concat(responses)); } }); command = commands.shift(); if (debug) { console.log('(Secure) C: ' + command); } secureSocket.write(command + '\r\n'); }); secureSocket.on('error', err => { console.log('SECURE ERR'); console.log(err.stack); }); } else { if (!/\r?\n$/.test(chunk.toString('binary'))) { return; } // only go forward with the next command if the last data ends with a newline // and there is no activity in the socket for 10ms clearTimeout(delay); delay = setTimeout(() => { command = commands.shift(); if (Array.isArray(command)) { let i = 0; let send = function () { if (i >= command.length) { return; } let part = command[i++]; socket.write(new Buffer(part + (i >= command.length ? '\r\n' : ''), 'binary')); if (debug) { console.log('C: ' + part); } setTimeout(send, 10); }; send(); } else { socket.write(new Buffer(command + '\r\n', 'binary')); if (debug) { console.log('C: ' + command); } } }, 10); } }; socket.on('data', onData); }); }