[Twisted-Python] Do Twisted support LMTP servers?
![](https://secure.gravatar.com/avatar/e024dc058df1df5cd0266f2f4f4dcd3b.jpg?s=120&d=mm&r=g)
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Twisted is very extensive in protocol support, managing smtp, pop3 and imap4, for example. I was wondering if there is any LMTP server project out there. It should be fairly simple, since LMTP is very very similar to usual SMTP. I need to use LMTP for a local project, and I was wondering if tiwsted could be used to fill this gap. - -- Jesus Cea Avion _/_/ _/_/_/ _/_/_/ jcea@argo.es http://www.argo.es/~jcea/ _/_/ _/_/ _/_/ _/_/ _/_/ jabber / xmpp:jcea@jabber.org _/_/ _/_/ _/_/_/_/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/ "El amor es poner tu felicidad en la felicidad de otro" - Leibniz -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQCVAwUBRDb7+plgi5GaxT1NAQK4rQP9EDdkMc0b83teXKB/XM22fV2gq3z/uEj1 RBjeHGSPOs5ogg1+/E4eiq8vq83mNTBDzxVJriN20UbrHgOcC+kBjfnCB8MCPnER 1tEorRnb19Siy+xnu0+rJ3XtNLJXJubMiXxm/5ig27Hl+UChnQLCthiqL1h0P22/ yi9LCprkRZ4= =fG6b -----END PGP SIGNATURE-----
![](https://secure.gravatar.com/avatar/32b6d2eaff3ae0d3e94ceb572cd63454.jpg?s=120&d=mm&r=g)
Jesus Cea wrote:
Hi, I have been looking at ways to have postfix talking to my twisted app and today tried LMTP successfully for the first time. What I've done so far is just subclass the ESMTP protocol and add do_LHLO which seems to do the trick for some basic usage at least. Looking at http://www.ietf.org/rfc/rfc2033.txt it seems like it shouldn't be to hard to make a proper LMTP implementation. Perhaps someone more familiar with twisted.mail could have a look. class LMTP(smtp.ESMTP): def do_LHLO(self, rest): peer = self.transport.getPeer() try: host = peer.host except AttributeError: host = str(peer) self._helo = (rest, host) self._from = None self._to = [] self.sendCode(250, '%s Hello %s, nice to meet you\n%s' % (self.host, host,self.listExtensions())) def do_HELO(self,rest): return self.do_UNKNOWN(self,rest) def do_EHLO(self,rest): return self.do_UNKNOWN(self,rest)
![](https://secure.gravatar.com/avatar/e024dc058df1df5cd0266f2f4f4dcd3b.jpg?s=120&d=mm&r=g)
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Simon Hedberg wrote:
Your mini LMTP implementation fails if a message is sent to several recipients, since LMTP must answer with a status code per destination. That is the main difference with SMTP. But good starting point :) Hope "somebody" takes the token and complete a RFC compliant implementation... :-p - -- Jesus Cea Avion _/_/ _/_/_/ _/_/_/ jcea@argo.es http://www.argo.es/~jcea/ _/_/ _/_/ _/_/ _/_/ _/_/ jabber / xmpp:jcea@jabber.org _/_/ _/_/ _/_/_/_/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/ "El amor es poner tu felicidad en la felicidad de otro" - Leibniz -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQCVAwUBREUJTZlgi5GaxT1NAQKU1wP6A6YMIvbb9qzT1ujbGo58Phq1Zc5amOxG eV+2YaDxNcGO7AE6OvSPfx0FXyc8hPU+jyh2PvnJMuII2pTqDidaVlXGh6bdRB7b w+yGY632rldOyVWOM8Rizl4jZha4LwfVc1Om2oUGvUxXG7iT+z6AjEY3zor2TTqC ucFVkMD0dWE= =KmBp -----END PGP SIGNATURE-----
![](https://secure.gravatar.com/avatar/32b6d2eaff3ae0d3e94ceb572cd63454.jpg?s=120&d=mm&r=g)
Jesus Cea wrote:
Ok, I had a closer look and here's a more complete version, that sends a status code for each recipient. Try it out /Simon class LMTP(smtp.ESMTP): def do_LHLO(self, rest): peer = self.transport.getPeer() try: host = peer.host except AttributeError: host = str(peer) self._helo = (rest, host) self._from = None self._to = [] self.sendCode(250, '%s Hello %s, nice to meet you\n%s' % (self.host, host,self.listExtensions())) def do_HELO(self,rest): return self.do_UNKNOWN(self,rest) def do_EHLO(self,rest): return self.do_UNKNOWN(self,rest) def _messageHandled(self, resultList): for (success, result) in resultList: if success: self.sendCode(250, 'OK') else: log.err(result) code = 550 msg = 'Could not deliver e-mail' smtperr = result.check(smtp.SMTPClientError) if smtperr: code = result.value.code msg = result.value.resp self.sendCode(code, msg)
![](https://secure.gravatar.com/avatar/e024dc058df1df5cd0266f2f4f4dcd3b.jpg?s=120&d=mm&r=g)
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Simon Hedberg wrote:
Thanks. I finally buried twisted and did the work with threads. Yes, I hear you cry :-). - -- Jesus Cea Avion _/_/ _/_/_/ _/_/_/ jcea@argo.es http://www.argo.es/~jcea/ _/_/ _/_/ _/_/ _/_/ _/_/ jabber / xmpp:jcea@jabber.org _/_/ _/_/ _/_/_/_/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/ "El amor es poner tu felicidad en la felicidad de otro" - Leibniz -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQCVAwUBRIX/xJlgi5GaxT1NAQLEUwP+PIt2CyT6jCB9x7/h9YR8bkgofNOGJXRl qr5faPgpPGbC8OIv4dOQAD/bvMKryOpDGTF5Sv++CNwRgufp9utcYcaAXhYS+54k 95uzAonVn0p0BYPwDuJLddN1IVfYsD6aVFUje474m2in8+H2NwZLR/r3G1u5ouOA 5V6tQeeD2Ls= =3lFE -----END PGP SIGNATURE-----
![](https://secure.gravatar.com/avatar/32b6d2eaff3ae0d3e94ceb572cd63454.jpg?s=120&d=mm&r=g)
Jesus Cea wrote:
Hi, I have been looking at ways to have postfix talking to my twisted app and today tried LMTP successfully for the first time. What I've done so far is just subclass the ESMTP protocol and add do_LHLO which seems to do the trick for some basic usage at least. Looking at http://www.ietf.org/rfc/rfc2033.txt it seems like it shouldn't be to hard to make a proper LMTP implementation. Perhaps someone more familiar with twisted.mail could have a look. class LMTP(smtp.ESMTP): def do_LHLO(self, rest): peer = self.transport.getPeer() try: host = peer.host except AttributeError: host = str(peer) self._helo = (rest, host) self._from = None self._to = [] self.sendCode(250, '%s Hello %s, nice to meet you\n%s' % (self.host, host,self.listExtensions())) def do_HELO(self,rest): return self.do_UNKNOWN(self,rest) def do_EHLO(self,rest): return self.do_UNKNOWN(self,rest)
![](https://secure.gravatar.com/avatar/e024dc058df1df5cd0266f2f4f4dcd3b.jpg?s=120&d=mm&r=g)
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Simon Hedberg wrote:
Your mini LMTP implementation fails if a message is sent to several recipients, since LMTP must answer with a status code per destination. That is the main difference with SMTP. But good starting point :) Hope "somebody" takes the token and complete a RFC compliant implementation... :-p - -- Jesus Cea Avion _/_/ _/_/_/ _/_/_/ jcea@argo.es http://www.argo.es/~jcea/ _/_/ _/_/ _/_/ _/_/ _/_/ jabber / xmpp:jcea@jabber.org _/_/ _/_/ _/_/_/_/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/ "El amor es poner tu felicidad en la felicidad de otro" - Leibniz -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQCVAwUBREUJTZlgi5GaxT1NAQKU1wP6A6YMIvbb9qzT1ujbGo58Phq1Zc5amOxG eV+2YaDxNcGO7AE6OvSPfx0FXyc8hPU+jyh2PvnJMuII2pTqDidaVlXGh6bdRB7b w+yGY632rldOyVWOM8Rizl4jZha4LwfVc1Om2oUGvUxXG7iT+z6AjEY3zor2TTqC ucFVkMD0dWE= =KmBp -----END PGP SIGNATURE-----
![](https://secure.gravatar.com/avatar/32b6d2eaff3ae0d3e94ceb572cd63454.jpg?s=120&d=mm&r=g)
Jesus Cea wrote:
Ok, I had a closer look and here's a more complete version, that sends a status code for each recipient. Try it out /Simon class LMTP(smtp.ESMTP): def do_LHLO(self, rest): peer = self.transport.getPeer() try: host = peer.host except AttributeError: host = str(peer) self._helo = (rest, host) self._from = None self._to = [] self.sendCode(250, '%s Hello %s, nice to meet you\n%s' % (self.host, host,self.listExtensions())) def do_HELO(self,rest): return self.do_UNKNOWN(self,rest) def do_EHLO(self,rest): return self.do_UNKNOWN(self,rest) def _messageHandled(self, resultList): for (success, result) in resultList: if success: self.sendCode(250, 'OK') else: log.err(result) code = 550 msg = 'Could not deliver e-mail' smtperr = result.check(smtp.SMTPClientError) if smtperr: code = result.value.code msg = result.value.resp self.sendCode(code, msg)
![](https://secure.gravatar.com/avatar/e024dc058df1df5cd0266f2f4f4dcd3b.jpg?s=120&d=mm&r=g)
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Simon Hedberg wrote:
Thanks. I finally buried twisted and did the work with threads. Yes, I hear you cry :-). - -- Jesus Cea Avion _/_/ _/_/_/ _/_/_/ jcea@argo.es http://www.argo.es/~jcea/ _/_/ _/_/ _/_/ _/_/ _/_/ jabber / xmpp:jcea@jabber.org _/_/ _/_/ _/_/_/_/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/ "El amor es poner tu felicidad en la felicidad de otro" - Leibniz -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQCVAwUBRIX/xJlgi5GaxT1NAQLEUwP+PIt2CyT6jCB9x7/h9YR8bkgofNOGJXRl qr5faPgpPGbC8OIv4dOQAD/bvMKryOpDGTF5Sv++CNwRgufp9utcYcaAXhYS+54k 95uzAonVn0p0BYPwDuJLddN1IVfYsD6aVFUje474m2in8+H2NwZLR/r3G1u5ouOA 5V6tQeeD2Ls= =3lFE -----END PGP SIGNATURE-----
participants (2)
-
Jesus Cea
-
Simon Hedberg