haraka / Haraka

A fast, highly extensible, and event driven SMTP server
https://haraka.github.io
MIT License
5.08k stars 661 forks source link

Inbound mail plugin this.loginfo. stops working after next(OK) #362

Closed TellusTalk closed 11 years ago

TellusTalk commented 11 years ago

Hi! My plugin transfers all inbound mail to our server using Http Post.

1) Plugin Saves inbound mail to disk 2) Plugin rases next(OK); 3) Plugin Http Post file to server (can take quite a while)

Quite often I can't find the entries in the syslog of the HttpPost status.

I think this depends on the "connection/this" object is destroyed when Haraka closes the connection with the remote email server, before the HttpPost is finished .

Thanks for help

Below my plugin

var fs = require('fs'); var http = require('http'); var DROP_DIRECTORY_PATH = '/tellustalk/haraka/drop/'; var RETRY_DIRECTORY_PATH = '/tellustalk/haraka/retry/';

exports.hook_queue = function(next, connection, params) {

function haraka_log(function_name_in, section_in, text_in) {
    var log_text = '';
    log_text += function_name_in + ' [ ' + section_in + ' ]\n';
    log_text += text_in;
    haraka_this.loginfo(log_text);
}//function haraka_log

function move_file(filename_in) {
    fs.rename(DROP_DIRECTORY_PATH + filename_in, RETRY_DIRECTORY_PATH + filename_in, function (err) {
        if (err) {
            //throw err;
            haraka_log('HttpPostData', 'fs.rename ... failed', filename_in + '\n' + JSON.stringify(err));
        } else {
            haraka_log('HttpPostData', 'fs.rename ... success', filename_in);
        }
    });
}//function move_file

function delete_file(filename_in) {
    fs.unlink(DROP_DIRECTORY_PATH + filename_in, function (err) {
        if (err) {
            //throw err;
            haraka_log('HttpPostData', 'fs.unlink ... failed', filename_in + '\n' + JSON.stringify(err));
        } else {
            haraka_log('HttpPostData', 'fs.unlink ... success', filename_in);
        }
    });
}//function delete_file

function HttpPostData(filename_in) {
    var
        post_options = {
            host: 'cloud.tellustalk.com',
            port: 80,
            path: '/http_mail/future',
            method: 'POST',
            headers: {'Content-Type': 'text/plain'}
        },
        post_request,
        read_stream;

    haraka_log('HttpPostData', 'Before http.request', filename_in);

    post_request = http.request(post_options, function(post_response) {
        haraka_log('HttpPostData', 'post_response', ' post_response.statusCode = ' + post_response.statusCode + ' : ' + filename_in);

        if (post_response.statusCode === 200) {
            delete_file(filename_in);
        } else {
            move_file(filename_in);//Posted later by retry script;
        }

        /*
        post_response.setEncoding('utf8');
        post_response.on('data', function (chunk) {
            haraka_log('HttpPostData', 'http post_response_body', chunk);
        });
        */

    });//post_request = http.request(post_options, function(post_response) {

    post_request.on('error', function(err) {
        haraka_log('HttpPostData post_request.on(\'error\' ...)', err.message, filename_in);
        move_file(filename_in);
    });

    read_stream = fs.createReadStream(DROP_DIRECTORY_PATH + filename_in);
    read_stream.pipe(post_request);

}//function HttpPostData

var
    haraka_this = this,
    from_ip = connection.remote_ip,
    x_sender = connection.transaction.mail_from.original,
    x_recipients_string = connection.transaction.rcpt_to.join(';'),
    filename = x_sender + '_' + new Date().toISOString() + '_' + connection.uuid,
    writeStream;

connection.transaction.add_header('XX-Original-XRecipientList', x_recipients_string);
connection.transaction.add_header('XX-ClientIPAddress', from_ip);
connection.transaction.add_header('XX-Original-XSender', x_sender);

haraka_this.loginfo('Http Mail: ' + filename);

writeStream = fs.createWriteStream(DROP_DIRECTORY_PATH + filename);
connection.transaction.message_stream.pipe(writeStream, {dot_stuffing: true, ending_dot: true});

writeStream.on("close", function() {
    haraka_this.loginfo('File Saved!: ' + filename);

    next(OK);
    HttpPostData(filename);

    haraka_this.loginfo('After next(OK): ' + filename);
});

};//exports.hook_queue = function(next, connection, params) {

baudehlo commented 11 years ago

Correct. If you want to ensure the connection isn't gone away you need to take steps to make sure of that, such as doing what you want in data_post and not returning next() until everything is complete. Also sending OK (instead of no params, or CONT) will mean no more hooks can run after yours.

On 2013-09-15, at 7:38 PM, TellusTalk notifications@github.com wrote:

Hi! My plugin transfers all inbound mail to our server using Http Post.

1) Plugin Saves inbound mail to disk 2) Plugin rases next(OK); 3) Plugin Http Post file to server (can take quite a while)

Quite often I can't find the entries in the syslog of the HttpPost status.

I think this depends on the "connection/this" object is destroyed when Haraka closes the connection with the remote email server, before the HttpPost is finished .

Thanks for help

Below my plugin

var fs = require('fs'); var http = require('http'); var DROP_DIRECTORY_PATH = '/tellustalk/haraka/drop/'; var RETRY_DIRECTORY_PATH = '/tellustalk/haraka/retry/';

exports.hook_queue = function(next, connection, params) {

function haraka_log(function_name_in, section_in, text_in) { var log_text = ''; log_text += function_name_in + ' [ ' + section_in + ' ]\n'; log_text += text_in; haraka_this.loginfo(log_text); }//function haraka_log

function move_file(filename_in) { fs.rename(DROP_DIRECTORY_PATH + filename_in, RETRY_DIRECTORY_PATH + filename_in, function (err) { if (err) { //throw err; haraka_log('HttpPostData', 'fs.rename ... failed', filename_in + '\n' + JSON.stringify(err)); } else { haraka_log('HttpPostData', 'fs.rename ... success', filename_in); } }); }//function move_file

function delete_file(filename_in) { fs.unlink(DROP_DIRECTORY_PATH + filename_in, function (err) { if (err) { //throw err; haraka_log('HttpPostData', 'fs.unlink ... failed', filename_in + '\n' + JSON.stringify(err)); } else { haraka_log('HttpPostData', 'fs.unlink ... success', filename_in); } }); }//function delete_file

function HttpPostData(filename_in) { var post_options = { host: 'cloud.tellustalk.com', port: 80, path: '/http_mail/future', method: 'POST', headers: {'Content-Type': 'text/plain'} }, post_request, read_stream;

haraka_log('HttpPostData', 'Before http.request', filename_in);

post_request = http.request(post_options, function(post_response) {
    haraka_log('HttpPostData', 'post_response', ' post_response.statusCode = ' + post_response.statusCode + ' : ' + filename_in);

    if (post_response.statusCode === 200) {
        delete_file(filename_in);
    } else {
        move_file(filename_in);//Posted later by retry script;
    }

    /*
    post_response.setEncoding('utf8');
    post_response.on('data', function (chunk) {
        haraka_log('HttpPostData', 'http post_response_body', chunk);
    });
    */

});//post_request = http.request(post_options, function(post_response) {

post_request.on('error', function(err) {
    haraka_log('HttpPostData post_request.on(\'error\' ...)', err.message, filename_in);
    move_file(filename_in);
});

read_stream = fs.createReadStream(DROP_DIRECTORY_PATH + filename_in);
read_stream.pipe(post_request);

}//function HttpPostData

var haraka_this = this, from_ip = connection.remote_ip, x_sender = connection.transaction.mail_from.original, x_recipients_string = connection.transaction.rcpt_to.join(';'), filename = xsender + '' + new Date().toISOString() + '_' + connection.uuid, writeStream;

connection.transaction.add_header('XX-Original-XRecipientList', x_recipients_string); connection.transaction.add_header('XX-ClientIPAddress', from_ip); connection.transaction.add_header('XX-Original-XSender', x_sender);

haraka_this.loginfo('Http Mail: ' + filename);

writeStream = fs.createWriteStream(DROP_DIRECTORY_PATH + filename); connection.transaction.message_stream.pipe(writeStream, {dot_stuffing: true, ending_dot: true});

writeStream.on("close", function() { haraka_this.loginfo('File Saved!: ' + filename);

next(OK);
HttpPostData(filename);

haraka_this.loginfo('After next(OK): ' + filename);

}); };//exports.hook_queue = function(next, connection, params) {

— Reply to this email directly or view it on GitHub.

TellusTalk commented 11 years ago

I want to drop the connection to the remote email server asap (afraid the remote email server will time out and resend)

Shall I require logger as example below or is there some better/safer way?

Thanks /Peter

var logger = require('./logger');

function haraka_log(function_name_in, section_in, text_in) {

    var log_text = 'test: ';

    log_text += function_name_in + ' [ ' + section_in + ' ]\n';

    log_text += text_in;

    logger.loginfo(log_text);

}//function haraka_log
baudehlo commented 11 years ago

You can certainly do that yes. Well discovered!

On 2013-09-15, at 9:01 PM, TellusTalk notifications@github.com wrote:

I want to drop the connection to the remote email server asap (afraid the remote email server will time out and resend)

Shall I require logger as example below or is there some better/safer way?

Thanks /Peter

var logger = require('./logger');

function haraka_log(function_name_in, section_in, text_in) {

var log_text = 'test: ';

log_text += function_name_in + ' [ ' + section_in + ' ]\n';

log_text += text_in;

logger.loginfo(log_text);

}//function haraka_log — Reply to this email directly or view it on GitHub.

TellusTalk commented 11 years ago

Thanks /Peter