wildduck/imap-core/test/test-client.js

153 lines
5.2 KiB
JavaScript
Raw Normal View History

2017-03-06 05:45:50 +08:00
/*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;
2017-12-13 16:33:13 +08:00
let socket = (options.secure ? tls : net).connect(
{
rejectUnauthorized: false,
port,
host
},
() => {
socket.on('close', () => {
if (callbackSent) {
2017-03-06 05:45:50 +08:00
return;
}
2017-12-13 16:33:13 +08:00
callbackSent = true;
if (typeof callback === 'function') {
return callback(Buffer.concat(responses));
}
});
2017-03-06 05:45:50 +08:00
2017-12-13 16:33:13 +08:00
let onData = function(chunk) {
if (ignore_data) {
return;
2017-03-06 05:45:50 +08:00
}
2017-12-13 16:33:13 +08:00
responses.push(chunk);
if (debug) {
console.log('S: ' + chunk.toString('binary').trim());
}
2017-03-06 05:45:50 +08:00
2017-12-13 16:33:13 +08:00
if (!commands.length) {
return;
}
2017-03-06 05:45:50 +08:00
2017-12-13 16:33:13 +08:00
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;
2017-03-06 05:45:50 +08:00
}
2017-12-13 16:33:13 +08:00
ignore_data = true;
2017-03-06 05:45:50 +08:00
if (debug) {
2017-12-13 16:33:13 +08:00
console.log('Initiated TLS connection');
2017-03-06 05:45:50 +08:00
}
2017-12-13 16:33:13 +08:00
socket.removeAllListeners('data');
let secureSocket = tls.connect(
{
rejectUnauthorized: false,
socket,
host
},
() => {
ignore_data = false;
2017-03-06 05:45:50 +08:00
2017-12-13 16:33:13 +08:00
socket = secureSocket;
if (debug) {
console.log('TLS connection secured');
2017-03-06 05:45:50 +08:00
}
2017-12-13 16:33:13 +08:00
secureSocket.on('data', onData);
secureSocket.on('close', () => {
if (callbackSent) {
return;
}
callbackSent = true;
if (typeof callback === 'function') {
return callback(Buffer.concat(responses));
}
});
2017-03-06 05:45:50 +08:00
2017-12-13 16:33:13 +08:00
command = commands.shift();
2017-03-06 05:45:50 +08:00
if (debug) {
2017-12-13 16:33:13 +08:00
console.log('(Secure) C: ' + command);
2017-03-06 05:45:50 +08:00
}
2017-12-13 16:33:13 +08:00
secureSocket.write(command + '\r\n');
2017-03-06 05:45:50 +08:00
}
2017-12-13 16:33:13 +08:00
);
secureSocket.on('error', err => {
console.log('SECURE ERR');
console.log(err.stack);
});
} else {
if (!/\r?\n$/.test(chunk.toString('binary'))) {
return;
2017-03-06 05:45:50 +08:00
}
2017-12-13 16:33:13 +08:00
// 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
let processCommand = () => {
clearTimeout(delay);
delay = setTimeout(() => {
command = commands.shift();
if (command === 'SLEEP') {
return setTimeout(processCommand, 1000);
}
2017-03-06 05:45:50 +08:00
2017-12-13 16:33:13 +08:00
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);
};
processCommand();
}
};
2017-03-06 05:45:50 +08:00
2017-12-13 16:33:13 +08:00
socket.on('data', onData);
}
);
2017-03-06 05:45:50 +08:00
}