On 8/29/07, <b class="gmail_sendername">Peter Ehrenberg</b> &lt;<a href="mailto:pe@dipe.de">pe@dipe.de</a>&gt; wrote:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Is anybody out there witch has already implemented a SMTP<br>server protocol handler for event machine?</blockquote><div><br><br>Ok, so here&#39;s an outline of what I have. I&#39;ve been developing this in C++ as a Ruby extension, but shifted to pure Ruby just for the sake of getting it out there more quickly. (Eventually it will shift back to C++, since EventMachine is starting to be used in non-Ruby environments.)
<br></div><br><br>There is a new class called EventMachine::SmtpServer, which subclasses EventMachine::Connection. Your code would subclass EM::SmtpServer, and you would override specific methods that will be called automatically at certain points during the processing of incoming SMTP transactions. This allows you to customize the behavior of the server in a fine-grained way.
<br><br>For example, you will get individual callbacks containing the domain name in the EHLO statement, the mail sender (MAIL FROM:), the recipients (RCPT TO:) and the message headers and body (DATA). You can specify whether you want to get the data line by line (appropriate for huge messages you may want to buffer yourself) or just get one callback with the whole message.
<br><br><br>Sample code:<br><br>#---------------------------------------------------------------------<br><br>require &#39;rubygems&#39;<br>require &#39;eventmachine&#39;<br><br>class MyClass &lt; EM::SmtpServer<br><br>&nbsp; def initialize *args
<br>&nbsp;&nbsp;&nbsp; super<br>&nbsp; end<br><br>&nbsp; def receive_mail_from( sender )<br>&nbsp;&nbsp;&nbsp; # do something and return true/false to accept/reject the sender<br>&nbsp; end<br><br>&nbsp; def receive_rcpt_to( recipients )<br>&nbsp;&nbsp;&nbsp; # recipients is a Ruby Array. return an array of true/falses.
<br>&nbsp; end<br><br>&nbsp; def receive_message( headers, data )<br>&nbsp;&nbsp;&nbsp; # process the message and reset internal buffers for the next one.<br>&nbsp; end<br><br>end<br><br><br>EM.run {<br>&nbsp; EM.start_server &quot;<a href="http://0.0.0.0">
0.0.0.0</a>&quot;, 25, MyClass<br>}<br><br>#--------------------------------------------------------------------<br><br><br>Was that more or less what you had in mind?<br><br></div>