mini-smtp-server 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Aaron Gough (http://thingsaaronmade.com/)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,78 @@
1
+ = mini-smtp-server
2
+
3
+ MiniSmtpServer is a small and easily customizable SMTP server. It is designed mainly to be integrated into other systems that will decide what to do with the mail that is received. By default mini-smtp-server operates as a black-hole and does not do anything with the mail being sent to it... Don't let that discourage you though, as MiniSmtpServer is designed to be extremely easy to customize which makes it fit more easily into your system!
4
+
5
+ === Using the server
6
+
7
+ To run the default server simply use:
8
+
9
+ # Create a new server instance listening at 127.0.0.1:2525
10
+ # and accepting a maximum of 4 simultaneous connections
11
+ server = MiniSmtpServer.new(2525, "127.0.0.1", 4)
12
+
13
+ # Start the server
14
+ server.start
15
+
16
+ # ...
17
+ # serving requests & doing other work here
18
+ # ...
19
+
20
+ # Shutdown the server without interrupting any connections:
21
+ server.shutdown
22
+ while(server.connections > 0)
23
+ sleep 0.01
24
+ end
25
+ server.stop
26
+ server.join
27
+
28
+ === Installation
29
+
30
+ For convenience MiniSmtpServer is packaged as a RubyGem, to install it simply enter the following at your command line:
31
+
32
+ gem install mini-smtp-server
33
+
34
+ === Customizing the server
35
+
36
+ MiniSmtpServer is designed to be easy to customize via subclassing. Simply subclass the `MiniSmtpServer` class and re-define the `new_message_event` event handler:
37
+
38
+ # This is an SMTP server that logs all
39
+ # the messages it receives to STDOUT
40
+ class StdoutSmtpServer < MiniSmtpServer
41
+
42
+ def new_message_event(message_hash)
43
+ puts "# New email received:"
44
+ puts "-- From: #{message_hash[:from]}"
45
+ puts "-- To: #{message_hash[:to]}"
46
+ puts "--"
47
+ puts "-- " + message_hash[:data].gsub(/\r\n/, "\r\n-- ")
48
+ puts
49
+ end
50
+
51
+ end
52
+
53
+ Then create an instance of your new server and run it like you would normally:
54
+
55
+ server = StdoutSmtpServer.new
56
+ server.start
57
+ server.join
58
+
59
+ The possibilities are endless, and easy to implement! Want all your email stored in a database? No worries:
60
+
61
+ class DatabaseSmtpServer < MiniSmtpServer
62
+ def new_message_event(message_hash)
63
+ # Imagine we have an ActiveRecord model named 'Email'
64
+ Email.create(message_hash)
65
+ end
66
+ end
67
+
68
+ # Presto!
69
+
70
+ If you have a great example of something you've done with MiniSmtpServer let me know and I will add it here!
71
+
72
+ === Author & Credits
73
+
74
+ Author:: {Aaron Gough}[mailto:aaron@aarongough.com]
75
+
76
+ MiniSmtpServer is based on code originally written by {Peter Cooper}[http://peterc.org/]
77
+
78
+ Copyright (c) 2010 {Aaron Gough}[http://thingsaaronmade.com/] ({thingsaaronmade.com}[http://thingsaaronmade.com/]), released under the MIT license
@@ -0,0 +1,42 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ begin
9
+ require 'jeweler'
10
+ Jeweler::Tasks.new do |gemspec|
11
+ gemspec.name = "mini-smtp-server"
12
+ gemspec.summary = "A small and simple SMTP server"
13
+ gemspec.description = "A small and simple SMTP server"
14
+ gemspec.email = "aaron@aarongough.com"
15
+ gemspec.homepage = "https://github.com/aarongough/mini-smtp-server"
16
+ gemspec.authors = ["Aaron Gough"]
17
+ gemspec.rdoc_options << '--line-numbers' << '--inline-source'
18
+ gemspec.extra_rdoc_files = ['README.rdoc', 'MIT-LICENSE']
19
+ end
20
+ rescue LoadError
21
+ puts "Jeweler not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+
25
+ desc 'Test mini-smtp-server.'
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib/*.rb'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = true
31
+ end
32
+
33
+
34
+ desc 'Generate documentation for mini-smtp-server.'
35
+ Rake::RDocTask.new(:rdoc) do |rdoc|
36
+ rdoc.rdoc_dir = 'rdoc'
37
+ rdoc.title = 'ruby-tmdb'
38
+ rdoc.options << '--line-numbers' << '--inline-source'
39
+ rdoc.rdoc_files.include('README.rdoc')
40
+ rdoc.rdoc_files.include('lib/**/*.rb')
41
+ rdoc.rdoc_files.include('app/**/*.rb')
42
+ end
@@ -0,0 +1 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "mini-smtp-server", "mini-smtp-server.rb"))
@@ -0,0 +1,72 @@
1
+ require 'gserver'
2
+
3
+ class MiniSmtpServer < GServer
4
+
5
+ def initialize(port = 2525, host = "127.0.0.1", max_connections = 4, *args)
6
+ super(port, host, max_connections, *args)
7
+ end
8
+
9
+ def serve(io)
10
+ @data_mode = false
11
+ @message = {:data => ""}
12
+ @connection_active = true
13
+ io.print "220 hello\r\n"
14
+ loop do
15
+ if IO.select([io], nil, nil, 0.1)
16
+ data = io.readpartial(4096)
17
+ log("<<< " + data) if(@audit)
18
+ output = process_line(data)
19
+ log(">>> " + output) if(@audit && !output.empty?)
20
+ io.print(output) unless output.empty?
21
+ end
22
+ break if(!@connection_active || io.closed?)
23
+ end
24
+ io.print "221 bye\r\n"
25
+ io.close
26
+ @message[:data].gsub!(/\r\n\Z/, '').gsub!(/\.\Z/, '')
27
+ new_message_event(@message)
28
+ end
29
+
30
+ def process_line(line)
31
+ # Handle specific messages from the client
32
+ case line
33
+ when (/^(HELO|EHLO)/)
34
+ return "220 go on...\r\n"
35
+ when (/^QUIT/)
36
+ @connection_active = false
37
+ return ""
38
+ when (/^MAIL FROM\:/)
39
+ @message[:from] = line.gsub(/^MAIL FROM\:/, '').strip
40
+ return "220 OK\r\n"
41
+ when (/^RCPT TO\:/)
42
+ @message[:to] = line.gsub(/^RCPT TO\:/, '').strip
43
+ return "220 OK\r\n"
44
+ when (/^DATA/)
45
+ @data_mode = true
46
+ return "354 Enter message, ending with \".\" on a line by itself\r\n"
47
+ end
48
+
49
+ # If we are in data mode and the entire message consists
50
+ # solely of a period on a line by itself then we
51
+ # are being told to exit data mode
52
+ if((@data_mode) && (line.chomp =~ /^\.$/))
53
+ @message[:data] += line
54
+ @data_mode = false
55
+ return "220 OK\r\n"
56
+ end
57
+
58
+ # If we are in date mode then we need to add
59
+ # the new data to the message
60
+ if(@data_mode)
61
+ @message[:data] += line
62
+ return ""
63
+ else
64
+ # If we somehow get to this point then
65
+ # we have encountered an error
66
+ return "500 ERROR\r\n"
67
+ end
68
+ end
69
+
70
+ def new_message_event(message_hash)
71
+ end
72
+ end
@@ -0,0 +1 @@
1
+ tmdb_api_key.txt
@@ -0,0 +1,13 @@
1
+ module Test::Unit::Assertions
2
+
3
+ def assert_difference(measure, difference = 1)
4
+ before = eval(measure)
5
+ yield
6
+ after = eval(measure)
7
+ message = "Expected '#{measure}' to be: #{before + difference} but was: #{after}\n"
8
+ assert_block(message) do
9
+ after == (before + difference)
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,21 @@
1
+ module Test::Unit
2
+ # Used to fix a minor minitest/unit incompatibility in flexmock
3
+ AssertionFailedError = Class.new(StandardError)
4
+
5
+ class TestCase
6
+
7
+ def self.test(name, &block)
8
+ test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
9
+ defined = instance_method(test_name) rescue false
10
+ raise "#{test_name} is already defined in #{self}" if defined
11
+ if block_given?
12
+ define_method(test_name, &block)
13
+ else
14
+ define_method(test_name) do
15
+ flunk "No implementation provided for #{name}"
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'net/smtp'
4
+
5
+ require_files = []
6
+ require_files << File.join(File.dirname(__FILE__), '..', 'lib', 'mini-smtp-server.rb')
7
+ require_files.concat Dir[File.join(File.dirname(__FILE__), 'setup', '*.rb')]
8
+
9
+ require_files.each do |file|
10
+ require File.expand_path(file)
11
+ end
@@ -0,0 +1,80 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper.rb'))
2
+
3
+ class TestSmtpServer < MiniSmtpServer
4
+ def new_message_event(message_hash)
5
+ $messages << message_hash
6
+ end
7
+ end
8
+
9
+ $example_mail = <<EOD
10
+ From: Your Name <your@mail.address>
11
+ To: Destination Address <someone@example.com>
12
+ Subject: test message
13
+ Date: Sat, 23 Jun 2001 16:26:43 +0900
14
+ Message-Id: <unique.message.id.string@example.com>
15
+
16
+ This is a test message.
17
+ EOD
18
+
19
+ class MiniSmtpServerTest < Test::Unit::TestCase
20
+
21
+ def setup
22
+ $messages = []
23
+ @server = TestSmtpServer.new(1234)
24
+ @server.start
25
+ end
26
+
27
+ test "should receive new message" do
28
+ assert_difference("$messages.length") do
29
+ send_mail
30
+ end
31
+ end
32
+
33
+ test "should receive 10 new messages" do
34
+ assert_difference("$messages.length", 10) do
35
+ 10.times do
36
+ send_mail
37
+ end
38
+ end
39
+ end
40
+
41
+ test "should store email from address in hash" do
42
+ assert_difference("$messages.length") do
43
+ send_mail
44
+ end
45
+ assert_equal "<smtp@test.com>", $messages.first[:from]
46
+ end
47
+
48
+ test "should store email to address in hash" do
49
+ assert_difference("$messages.length") do
50
+ send_mail
51
+ end
52
+ assert_equal "<some1@test.com>", $messages.first[:to]
53
+ end
54
+
55
+ test "should store email body in message hash" do
56
+ assert_difference("$messages.length") do
57
+ send_mail
58
+ end
59
+ assert_equal $example_mail.gsub("\n", "\r\n"), $messages.first[:data]
60
+ end
61
+
62
+ def teardown
63
+ @server.shutdown
64
+ while(@server.connections > 0)
65
+ end
66
+ @server.stop
67
+ @server.join
68
+ end
69
+
70
+ private
71
+
72
+ def send_mail(message = $example_mail, from_address = "smtp@test.com", to_address = "some1@test.com")
73
+ Net::SMTP.start('127.0.0.1', 1234) do |smtp|
74
+ smtp.send_message(message, from_address, to_address)
75
+ smtp.finish
76
+ sleep 0.01
77
+ end
78
+ end
79
+
80
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mini-smtp-server
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Aaron Gough
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-05 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: A small and simple SMTP server
22
+ email: aaron@aarongough.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - MIT-LICENSE
29
+ - README.rdoc
30
+ files:
31
+ - MIT-LICENSE
32
+ - README.rdoc
33
+ - Rakefile
34
+ - lib/mini-smtp-server.rb
35
+ - lib/mini-smtp-server/mini-smtp-server.rb
36
+ - test/setup/.gitignore
37
+ - test/setup/custom_assertions.rb
38
+ - test/setup/test_unit_extensions.rb
39
+ - test/test_helper.rb
40
+ - test/unit/mini_smtp_server_test.rb
41
+ has_rdoc: true
42
+ homepage: https://github.com/aarongough/mini-smtp-server
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options:
47
+ - --charset=UTF-8
48
+ - --line-numbers
49
+ - --inline-source
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ requirements: []
69
+
70
+ rubyforge_project:
71
+ rubygems_version: 1.3.7
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: A small and simple SMTP server
75
+ test_files:
76
+ - test/setup/custom_assertions.rb
77
+ - test/setup/test_unit_extensions.rb
78
+ - test/test_helper.rb
79
+ - test/unit/mini_smtp_server_test.rb