# 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()
eventlet SMTP Relay server
最新推荐文章于 2024-06-23 09:46:51 发布