Created
June 1, 2014 15:07
-
-
Save araipiyo/f212d92bee1ad9afcf1d to your computer and use it in GitHub Desktop.
Simpliest mock SMTP server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'socket' | |
require 'nkf' | |
DEBUG = false | |
#KANJI = nil | |
KANJI = '-s' | |
def data(sock) | |
s = "" | |
sock.print "354 End data with <CR><LF>.<CR><LF>\r\n" | |
while(line = sock.gets) | |
puts line if DEBUG | |
break if line =~ /^\.\r?\n?$/ | |
s += line | |
end | |
s | |
end | |
def parse_message(s) | |
(header, body) = s.gsub(/\r\n/,"\n").split(/\n\n/,2) | |
headers = {} | |
header.gsub(/\n[\s\t]+/, ' ').split(/\n/).each { |line| | |
(k,v) = line.split(/: +/,2) | |
headers[k] = v | |
} | |
[headers, body] | |
end | |
def write(io, from, to, headers, body) | |
io.puts "envelope-from: #{from}" | |
io.puts "envelope-to: #{to.join '; '}" | |
io.puts "---" | |
headers.each { |k,v| io.puts "#{k}: #{v}" } | |
io.puts "\n\n" | |
io.puts body | |
io.puts "===" | |
end | |
def session(sock) | |
sock.print "220 localhost SMTP mockmail\r\n" | |
from = nil | |
to = [] | |
body = nil | |
while(line = sock.gets) | |
line.chomp! | |
puts line if DEBUG | |
sock.print case line | |
when /HELO/: "250 localhost\r\n" | |
when /RSET/: "250 Ok\r\n" | |
when /VRFY/: | |
/VRFY [^\s]/ =~ line | |
"252 #{$1}\r\n" | |
when /MAIL FROM/: | |
/MAIL FROM:\s*\<?([^\s<>]+)\>?/ =~ line | |
from = $1 | |
puts from if DEBUG | |
"250 Ok\r\n" | |
when /RCPT TO/: | |
/RCPT TO:\s*\<?([^\s\r\n\t\f<>]+)\>?/ =~ line | |
to << $1 | |
puts to if DEBUG | |
"250 Ok\r\n" | |
when /DATA/: | |
message = data(sock) | |
"250 Ok\r\n" | |
when /QUIT/: | |
sock.print "221 Bye\r\n" | |
break | |
else "500 Err\r\n" | |
end | |
end | |
(headers, body) = parse_message(message) | |
if KANJI | |
headers.each { |k,v| headers[k] = NKF.nkf(KANJI,v) } | |
end | |
if headers['Content-Transfer-Encoding'] == 'base64' | |
body = body.unpack('m')[0] | |
body = NKF.nkf(KANJI,body) if KANJI | |
end | |
write(STDOUT, from, to, headers, body) | |
open("mockmail.txt", "a") { |f| | |
write(f, from, to, headers, body) | |
} | |
sock.close | |
end | |
def main | |
begin | |
server = TCPServer.new('localhost',25) | |
Thread.start { | |
loop { sleep 1 } | |
} | |
loop do | |
Thread.start(server.accept) { |sock| | |
begin | |
session(sock) | |
rescue Exception => e | |
p e | |
end | |
} | |
end | |
rescue Interrupt => i | |
puts "ending..." | |
end | |
end | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment