123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- 'use strict';
- const packageData = require('../../package.json');
- const shared = require('../shared');
- const LeWindows = require('../sendmail-transport/le-windows');
- const LeUnix = require('../sendmail-transport/le-unix');
- /**
- * Generates a Transport object for streaming
- *
- * Possible options can be the following:
- *
- * * **buffer** if true, then returns the message as a Buffer object instead of a stream
- * * **newline** either 'windows' or 'unix'
- *
- * @constructor
- * @param {Object} optional config parameter
- */
- class StreamTransport {
- constructor(options) {
- options = options || {};
- this.options = options || {};
- this.name = 'StreamTransport';
- this.version = packageData.version;
- this.logger = shared.getLogger(this.options, {
- component: this.options.component || 'stream-transport'
- });
- this.winbreak = ['win', 'windows', 'dos', '\r\n'].includes((options.newline || '').toString().toLowerCase());
- }
- /**
- * Compiles a mailcomposer message and forwards it to handler that sends it
- *
- * @param {Object} emailMessage MailComposer object
- * @param {Function} callback Callback function to run when the sending is completed
- */
- send(mail, done) {
- // We probably need this in the output
- mail.message.keepBcc = true;
- let envelope = mail.data.envelope || mail.message.getEnvelope();
- let messageId = mail.message.messageId();
- let recipients = [].concat(envelope.to || []);
- if (recipients.length > 3) {
- recipients.push('...and ' + recipients.splice(2).length + ' more');
- }
- this.logger.info(
- {
- tnx: 'send',
- messageId
- },
- 'Sending message %s to <%s> using %s line breaks',
- messageId,
- recipients.join(', '),
- this.winbreak ? '<CR><LF>' : '<LF>'
- );
- setImmediate(() => {
- let sourceStream;
- let stream;
- let transform;
- try {
- transform = this.winbreak ? new LeWindows() : new LeUnix();
- sourceStream = mail.message.createReadStream();
- stream = sourceStream.pipe(transform);
- sourceStream.on('error', err => stream.emit('error', err));
- } catch (E) {
- this.logger.error(
- {
- err: E,
- tnx: 'send',
- messageId
- },
- 'Creating send stream failed for %s. %s',
- messageId,
- E.message
- );
- return done(E);
- }
- if (!this.options.buffer) {
- stream.once('error', err => {
- this.logger.error(
- {
- err,
- tnx: 'send',
- messageId
- },
- 'Failed creating message for %s. %s',
- messageId,
- err.message
- );
- });
- return done(null, {
- envelope: mail.data.envelope || mail.message.getEnvelope(),
- messageId,
- message: stream
- });
- }
- let chunks = [];
- let chunklen = 0;
- stream.on('readable', () => {
- let chunk;
- while ((chunk = stream.read()) !== null) {
- chunks.push(chunk);
- chunklen += chunk.length;
- }
- });
- stream.once('error', err => {
- this.logger.error(
- {
- err,
- tnx: 'send',
- messageId
- },
- 'Failed creating message for %s. %s',
- messageId,
- err.message
- );
- return done(err);
- });
- stream.on('end', () =>
- done(null, {
- envelope: mail.data.envelope || mail.message.getEnvelope(),
- messageId,
- message: Buffer.concat(chunks, chunklen)
- })
- );
- });
- }
- }
- module.exports = StreamTransport;
|