Ruby SMTP Server - Save to Database
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.
require 'gserver' require 'rubygems' require 'active_record' require 'yaml' dbconfig = YAML::load_file(File.dirname(__FILE__) + '/config/database.yml') ActiveRecord::Base.establish_connection(dbconfig['development']) class Email < ActiveRecord::Base end class SMTPServer < GServer def serve(io) @data_mode = false @email_message = "" puts "Connected" io.print "220 hello\r\n" loop do if IO.select([io], nil, nil, 0.1) data = io.readpartial(4096) puts ">>" + data @email_message << data ok, op = process_line(data) break unless ok puts "<<" + op io.print op end break if io.closed? end db_insert(@email_message) io.print "221 bye\r\n" io.close end def process_line(line) if (@data_mode) && (line.chomp =~ /^\.$/) @data_mode = false return true, "220 OK\r\n" elsif @data_mode return true, "" elsif (line =~ /^(HELO|EHLO)/) return true, "220 and..?\r\n" elsif (line =~ /^QUIT/) return false, "bye\r\n" elsif (line =~ /^MAIL FROM\:/) return true, "220 OK\r\n" elsif (line =~ /^RCPT TO\:/) return true, "220 OK\r\n" elsif (line =~ /^DATA/) @data_mode = true return true, "354 Enter message, ending with \".\" on a line by itself\r\n" else return true, "500 ERROR\r\n" end end def db_insert(email) mail_from = (/^MAIL FROM\:<(.+)>.*$/).match(email)[1] rcpt_to = (/^RCPT TO\:<(.+)>.*$/).match(email)[1] subject = (/^Subject\: (.+)$/).match(email)[1] Email.create(:mail_from => mail_from, :rcpt_to => rcpt_to, :subject => subject, :email => email) end end a = SMTPServer.new(25) a.start a.join