eventlet SMTP Relay server

# import the standard smtplib library
import smtplib
from eventlet import patcher
patcher.monkey_patch(all=False, socket=True) # patch socket and ssl

import eventlet
import sys
import email
import getopt

def local_property(func):
    return property(**func())

class SMTPRelayServer(object):
    def __init__(self, host=None, port=None, ssl=False, listen_addr=('0.0.0.0', 6000)):
        """host is the ip address of the server, can be optional
        port is the port of the server, can be optional
        if ssl is required to connect to the server, it must be True
        listen_addr is a tuple of current server address
        """

        self.address = listen_addr
        self.host = host
        self.host_port = port
        self.require_ssl = ssl
        self.pool = eventlet.GreenPool()
        self.send_addr = 'smtp_relay'

    @local_property
    def send_from():
        def fget(self):
            return self.send_addr

        def fset(self, v):
            self.send_addr = v

        return locals()

    @local_property
    def username():
        def fget(self):
            return self.user

        def fset(self, v):
            self.user = v

        return locals()

    @local_property
    def passwd():
        def fget(self):
            return self.pwd

        def fset(self, v):
            self.pwd = v

        return locals()

    def run(self):
        """main loop of the relay server"""

        self.server_sock = eventlet.listen(self.address)
        while True:
            new_sock, address = self.server_sock.accept()
            print 'incomming: ', address
            self.pool.spawn_n(self._handle, new_sock.makefile('r'))

    def shutdown(self):
        """shtudown the server"""

        self.server_sock.close()

    def _handle(self, sock):
        """client handler, forward the client data to the remote smtp server"""

        content = ''
        while True:
            data = sock.read()
            if not data: break
            content += data
        # client data is mail message, extract the From and To addresses
        msg = email.message_from_string(content)
        if msg['From']:
            from_addr = msg['From']
        else:
            from_addr = self.send_addr

        # only send the mail if To is not empty
        if msg['To']:
            if not self.require_ssl:
                smtp_server = smtplib.SMTP(self.host, self.host_port)
            else:
                smtp_server = smtplib.SMTP_SSL()
                smtp_server.connect(self.host, self.host_port)
                smtp_server.login(self.username, self.passwd)

            smtp_server.sendmail(from_addr, msg['To'], content)

    # context manager protocal
    def __enter__(self):
        return self

    def __exit__(self, exec_type, exec_value, traceback):
        self.shutdown()
        return False

if __name__ == '__main__':
    host = None
    port = None
    user = ''
    pwd  = ''
    ssl = False
    opts, args = getopt.getopt(sys.argv[1:], "", ['host=', 'port=', 'user=', 'pwd=', 'ssl'])
    for opt, arg in opts:
        if opt == '--host':
            host = arg
        elif opt == '--port':
            port = arg
        elif opt == '--user':
            user = arg
        elif opt == '--pwd':
            pwd = arg
        elif opt == '--ssl':
            ssl = True

    with SMTPRelayServer(host, port, ssl) as server:
        server.username = user
        server.passwd = pwd
        server.run()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值