Re: [exim] Loopy idea: "tunnel" SMTP through HTTP

Top Page
Delete this message
Reply to this message
Author: Jan-Piet Mens
Date:  
To: exim-users
CC: Greg Ward
Subject: Re: [exim] Loopy idea: "tunnel" SMTP through HTTP
On Tue Mar 14 2006 at 23:59:50 CET, Tony Finch wrote:

> I'd suggest configuring Exim on the crippled hosts to deliver BSMTP into a
> pipe which POSTs to the appropriate CGI on the web server. The CGI can
> then pipe the BSMTP straight into Exim. This should require almost no new
> code.


That is what I do, though the submission via HTTP is scheduled via cron.
(BTW: this will also work with sendmail, as message is simply piped to it)

Hope it helps.
    -JP


exim.configure
--------------

router:
batched_smtp:
driver = manualroute
senders = whatever.com
transport = bsmtp_appendfile

transport:
bsmtp_appendfile:
driver = appendfile
directory = /var/bsmtp/$host
batch_max = 1000
use_bsmtp
user = exim


cron:
----
*/15    *   *  *  * /usr/local/sbin/esubmit


esubmit:
---------
#!/bin/sh

spool="/var/bsmtp/batch.host"

if [ -d $spool ]; then
        cd $spool || exit 1


        ls | while read msgid
        do
                if [ -f "$msgid" ] ; then
                        /usr/local/sbin/esubmit.pl "$msgid" && mv -f "$msgid" /var/bsmtp/b/
                fi
        done
fi


esubmit.pl:
-----------
#!/usr/bin/perl

use strict;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);

my $url="http://my-site/support/exim/eget.cgi";

my $ua = LWP::UserAgent->new;
$ua->agent('esubmit/1.0 ' . $ua->_agent);

my $spooldir = '/var/bsmtp/batch.host";
my $msgid = $ARGV[0];
my $data;

die "Usage: #0 msgid" unless ($msgid);

open(SPOOL, "$spooldir/$msgid") or die "Can't open input $msgid: $!";
$data = '';
while (<SPOOL>) {
        $data .= $_;
}
close(SPOOL);
my $res = $ua->request(POST "$url",
        Content_Type => 'multipart/form-data',
        Content => [ qid => "$msgid",
                spoolfile => "$data",
                ]);


if ($res->is_success) {
        print $res->content;
        exit 0;
}
else {
        print $res->content;
        exit 1;
}
1;



eget.cgi (on the receiving side)
---------------------------------
#!/usr/bin/perl

use strict;
use CGI;

my $q = CGI->new;

my ($msgid, $data);
$msgid = $q->param('qid');
$data = $q->param('spoolfile');

if (!$msgid) {
        print "Content-type: text/plain\n\n";
        print "Message-ID is missing!. Quit\n";
        exit(0);
}


unless (open(EXIM, "|/usr/exim/bin/exim -bS 2>&1")) {
        print "Content-type: text/plain\n\n";
        die "Can't pipe to exim: $!";
        }
print EXIM "$data";
close(EXIM);


my $ret = "Thanks; got " . length($data) . " bytes for message $msgid\n";

print "Content-length: " . length($ret) . "\n";
print "Content-type: text/plain\n\n";

print "$ret";
exit 0;