<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: GServer code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Thu, 24 Jul 2008 08:39:27 GMT</pubDate>
    <description>DZone Snippets: GServer code</description>
    <item>
      <title>Ruby SMTP Server - Save to Database</title>
      <link>http://snippets.dzone.com/posts/show/5152</link>
      <description>This was something I've searched for in the past but have yet to find. It's a super simple server and I'm sure there's a few bugs left in it, but the idea is simple and in my opinion, necessary. It's easy to send email from websites, but receiving it still seems dubious.&lt;br /&gt;&lt;br /&gt;I've simply used Peter's(http://snippets.dzone.com/user/peter) ultra simplistic SMTP server and routed the email to a database table called "Emails" via ActiveRecord. It's running GServer so it should be able to handle a decent load. Like I mentioned earlier, it's probably still got some bugs, but it's a decent start.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require 'gserver'&lt;br /&gt;require 'rubygems'  &lt;br /&gt;require 'active_record'  &lt;br /&gt;require 'yaml'&lt;br /&gt;   &lt;br /&gt;dbconfig = YAML::load_file(File.dirname(__FILE__) + '/config/database.yml')&lt;br /&gt;ActiveRecord::Base.establish_connection(dbconfig['development']) &lt;br /&gt;&lt;br /&gt;class Email &lt; ActiveRecord::Base   &lt;br /&gt;end &lt;br /&gt;&lt;br /&gt;class SMTPServer &lt; GServer&lt;br /&gt;  def serve(io)&lt;br /&gt;    @data_mode = false&lt;br /&gt;    @email_message = ""&lt;br /&gt;    puts "Connected"&lt;br /&gt;    io.print "220 hello\r\n"&lt;br /&gt;    loop do&lt;br /&gt;      if IO.select([io], nil, nil, 0.1)&lt;br /&gt;	      data = io.readpartial(4096)&lt;br /&gt;	      puts "&gt;&gt;" + data&lt;br /&gt;	      @email_message &lt;&lt; data&lt;br /&gt;	      ok, op = process_line(data)&lt;br /&gt;	      break unless ok&lt;br /&gt;	      puts "&lt;&lt;" + op&lt;br /&gt;	      io.print op&lt;br /&gt;      end&lt;br /&gt;      break if io.closed?&lt;br /&gt;    end&lt;br /&gt;    db_insert(@email_message)&lt;br /&gt;    io.print "221 bye\r\n"&lt;br /&gt;    io.close&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def process_line(line)&lt;br /&gt;    if (@data_mode) &amp;&amp; (line.chomp =~ /^\.$/)&lt;br /&gt;      @data_mode = false&lt;br /&gt;      return true, "220 OK\r\n"&lt;br /&gt;    elsif @data_mode&lt;br /&gt;      return true, ""&lt;br /&gt;    elsif (line =~ /^(HELO|EHLO)/)&lt;br /&gt;      return true, "220 and..?\r\n"&lt;br /&gt;    elsif (line =~ /^QUIT/)&lt;br /&gt;      return false, "bye\r\n"&lt;br /&gt;    elsif (line =~ /^MAIL FROM\:/)&lt;br /&gt;      return true, "220 OK\r\n"&lt;br /&gt;    elsif (line =~ /^RCPT TO\:/)&lt;br /&gt;      return true, "220 OK\r\n"&lt;br /&gt;    elsif (line =~ /^DATA/)&lt;br /&gt;      @data_mode = true&lt;br /&gt;      return true, "354 Enter message, ending with \".\" on a line by itself\r\n"&lt;br /&gt;    else&lt;br /&gt;      return true, "500 ERROR\r\n"&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def db_insert(email)&lt;br /&gt;    mail_from = (/^MAIL FROM\:&lt;(.+)&gt;.*$/).match(email)[1]&lt;br /&gt;    rcpt_to = (/^RCPT TO\:&lt;(.+)&gt;.*$/).match(email)[1]&lt;br /&gt;    subject = (/^Subject\: (.+)$/).match(email)[1]&lt;br /&gt;    Email.create(:mail_from =&gt; mail_from, :rcpt_to =&gt; rcpt_to, :subject =&gt; subject, :email =&gt; email)&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;a = SMTPServer.new(25)&lt;br /&gt;a.start&lt;br /&gt;a.join&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Tue, 19 Feb 2008 07:56:06 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5152</guid>
      <author>markpercival (Mark Percival)</author>
    </item>
  </channel>
</rss>
