remailer 0.3.6 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ begin
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "remailer"
8
8
  gem.summary = %Q{Reactor-Ready SMTP Mailer}
9
- gem.description = %Q{EventMachine capable SMTP engine}
9
+ gem.description = %Q{EventMachine SMTP Mail User Agent}
10
10
  gem.email = "scott@twg.ca"
11
11
  gem.homepage = "http://github.com/twg/remailer"
12
12
  gem.authors = [ "Scott Tadman" ]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.6
1
+ 0.3.8
@@ -295,13 +295,18 @@ class Remailer::Connection < EventMachine::Connection
295
295
 
296
296
  @timeout_at = nil
297
297
 
298
- error_notification(:timeout, "Connection timed out")
299
- debug_notification(:timeout, "Connection timed out")
300
- message_callback(:timeout, "Connection timed out before send could complete")
301
-
302
- unless (@connected)
303
- connect_notification(false, "Connection timed out")
298
+ if (@connected and @active_message)
299
+ message_callback(:timeout, "Response timed out before send could complete")
300
+ error_notification(:timeout, "Response timed out")
301
+ debug_notification(:timeout, "Response timed out")
302
+ send_callback(:on_error)
303
+ elsif (!@connected)
304
+ connect_notification(false, "Timed out before a connection could be established")
305
+ debug_notification(:timeout, "Timed out before a connection could be established")
306
+ error_notification(:timeout, "Timed out before a connection could be established")
304
307
  send_callback(:on_error)
308
+ else
309
+ send_callback(:on_disconnect)
305
310
  end
306
311
 
307
312
  close_connection
@@ -341,6 +346,7 @@ class Remailer::Connection < EventMachine::Connection
341
346
  debug_notification(:closed, "Connection closed")
342
347
  super
343
348
  @closed = true
349
+ @timeout_at = nil
344
350
  end
345
351
  alias_method :close, :close_connection
346
352
 
@@ -401,8 +407,10 @@ class Remailer::Connection < EventMachine::Connection
401
407
  end
402
408
 
403
409
  def connect_notification(code, message = nil)
410
+ @connected = code
411
+
404
412
  send_notification(:connect, code, message || self.remote)
405
- send_callback(:on_connect)
413
+ send_callback(:on_connect) if (code)
406
414
  end
407
415
 
408
416
  def error_notification(code, message)
@@ -49,6 +49,15 @@ class Remailer::Connection::SmtpInterpreter < Remailer::Interpreter
49
49
  enter_state(:helo)
50
50
  end
51
51
  end
52
+
53
+ interpret(421) do |message|
54
+ delegate.connect_notification(false, "Connection timed out")
55
+ delegate.debug_notification(:error, "[#{@state}] 421 #{message}")
56
+ delegate.error_notification(421, message)
57
+ delegate.send_callback(:on_error)
58
+
59
+ enter_state(:terminated)
60
+ end
52
61
  end
53
62
 
54
63
  state :helo do
@@ -161,7 +170,12 @@ class Remailer::Connection::SmtpInterpreter < Remailer::Interpreter
161
170
 
162
171
  state :mail_from do
163
172
  enter do
164
- delegate.send_line("MAIL FROM:<#{delegate.active_message[:from]}>")
173
+ if (delegate.active_message)
174
+ delegate.send_line("MAIL FROM:<#{delegate.active_message[:from]}>")
175
+ else
176
+ delegate.message_callback(false, "Delegate has no active message")
177
+ enter_state(:reset)
178
+ end
165
179
  end
166
180
 
167
181
  interpret(250) do
@@ -171,7 +185,12 @@ class Remailer::Connection::SmtpInterpreter < Remailer::Interpreter
171
185
 
172
186
  state :rcpt_to do
173
187
  enter do
174
- delegate.send_line("RCPT TO:<#{delegate.active_message[:to]}>")
188
+ if (delegate.active_message)
189
+ delegate.send_line("RCPT TO:<#{delegate.active_message[:to]}>")
190
+ else
191
+ delegate.message_callback(false, "Delegate has no active message")
192
+ enter_state(:reset)
193
+ end
175
194
  end
176
195
 
177
196
  interpret(250) do
@@ -234,7 +253,7 @@ class Remailer::Connection::SmtpInterpreter < Remailer::Interpreter
234
253
 
235
254
  state :reset do
236
255
  enter do
237
- delegate.send_line("RESET")
256
+ delegate.send_line("RSET")
238
257
  end
239
258
 
240
259
  interpret(250) do
@@ -59,6 +59,11 @@ class Remailer::Interpreter
59
59
  StateProxy.new(config, &block)
60
60
  end
61
61
 
62
+ # This is a method to convert a spec and a block into a proper parser
63
+ # method. If spec is specified, it should be a Fixnum, or a Regexp. A
64
+ # Fixnum defines a minimum size to process, useful for packed binary
65
+ # streams, and a Regexp defines a pattern that must match before the parser
66
+ # is engaged.
62
67
  def self.parser_for_spec(spec, &block)
63
68
  case (spec)
64
69
  when nil
@@ -100,7 +105,7 @@ class Remailer::Interpreter
100
105
  @on_error = block
101
106
  end
102
107
 
103
- # Returns the currently defined parser.
108
+ # Returns the parser used when no state-specific parser has been defined.
104
109
  def self.default_parser
105
110
  @parser ||= lambda { |s| _s = s.dup; s.replace(''); _s }
106
111
  end
@@ -152,9 +157,10 @@ class Remailer::Interpreter
152
157
  end
153
158
 
154
159
  # Parses a given string and returns the first interpretable token, if any,
155
- # or nil otherwise. The string is not modified.
156
- def parse(s)
157
- instance_exec(s, &parser)
160
+ # or nil otherwise. If an interpretable token is found, the supplied string
161
+ # will be modified to have that matching portion removed.
162
+ def parse(buffer)
163
+ instance_exec(buffer, &parser)
158
164
  end
159
165
 
160
166
  # Returns the parser defined for the current state, or the default parser.
@@ -184,7 +190,8 @@ class Remailer::Interpreter
184
190
  # Interprets a given object with an optional set of arguments. The actual
185
191
  # interpretation should be defined by declaring a state with an interpret
186
192
  # block defined.
187
- def interpret(object, *args)
193
+ def interpret(*args)
194
+ object = args.first
188
195
  config = self.class.states[@state]
189
196
  callbacks = (config and config[:interpret])
190
197
 
@@ -194,16 +201,17 @@ class Remailer::Interpreter
194
201
  end
195
202
 
196
203
  if (matched)
204
+ args.shift
197
205
  instance_exec(*args, &proc)
198
206
 
199
207
  return true
200
208
  end
201
209
  end
202
210
 
203
- if (trigger_callbacks(@state, :default, *([ object ] + args)))
211
+ if (trigger_callbacks(@state, :default, *args))
204
212
  # Handled by default
205
213
  true
206
- elsif (proc = self.class.default)
214
+ elsif (proc = self.class.default_interpreter)
207
215
  instance_exec(*args, &proc)
208
216
  else
209
217
  if (proc = self.class.on_error_handler)
@@ -1,56 +1,54 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{remailer}
8
- s.version = "0.3.6"
8
+ s.version = "0.3.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Scott Tadman"]
12
- s.date = %q{2010-12-17}
13
- s.description = %q{EventMachine capable SMTP engine}
12
+ s.date = %q{2011-01-12}
13
+ s.description = %q{EventMachine SMTP Mail User Agent}
14
14
  s.email = %q{scott@twg.ca}
15
15
  s.extra_rdoc_files = [
16
16
  "README.rdoc"
17
17
  ]
18
18
  s.files = [
19
19
  ".document",
20
- ".gitignore",
21
- "README.rdoc",
22
- "Rakefile",
23
- "VERSION",
24
- "lib/remailer.rb",
25
- "lib/remailer/connection.rb",
26
- "lib/remailer/connection/smtp_interpreter.rb",
27
- "lib/remailer/connection/socks5_interpreter.rb",
28
- "lib/remailer/interpreter.rb",
29
- "lib/remailer/interpreter/state_proxy.rb",
30
- "remailer.gemspec",
31
- "test/config.example.rb",
32
- "test/helper.rb",
33
- "test/unit/remailer_connection_smtp_interpreter_test.rb",
34
- "test/unit/remailer_connection_socks5_interpreter_test.rb",
35
- "test/unit/remailer_connection_test.rb",
36
- "test/unit/remailer_interpreter_state_proxy_test.rb",
37
- "test/unit/remailer_interpreter_test.rb",
38
- "test/unit/remailer_test.rb"
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "lib/remailer.rb",
24
+ "lib/remailer/connection.rb",
25
+ "lib/remailer/connection/smtp_interpreter.rb",
26
+ "lib/remailer/connection/socks5_interpreter.rb",
27
+ "lib/remailer/interpreter.rb",
28
+ "lib/remailer/interpreter/state_proxy.rb",
29
+ "remailer.gemspec",
30
+ "test/config.example.rb",
31
+ "test/helper.rb",
32
+ "test/unit/remailer_connection_smtp_interpreter_test.rb",
33
+ "test/unit/remailer_connection_socks5_interpreter_test.rb",
34
+ "test/unit/remailer_connection_test.rb",
35
+ "test/unit/remailer_interpreter_state_proxy_test.rb",
36
+ "test/unit/remailer_interpreter_test.rb",
37
+ "test/unit/remailer_test.rb"
39
38
  ]
40
39
  s.homepage = %q{http://github.com/twg/remailer}
41
- s.rdoc_options = ["--charset=UTF-8"]
42
40
  s.require_paths = ["lib"]
43
41
  s.rubygems_version = %q{1.3.7}
44
42
  s.summary = %q{Reactor-Ready SMTP Mailer}
45
43
  s.test_files = [
46
44
  "test/config.example.rb",
47
- "test/helper.rb",
48
- "test/unit/remailer_connection_smtp_interpreter_test.rb",
49
- "test/unit/remailer_connection_socks5_interpreter_test.rb",
50
- "test/unit/remailer_connection_test.rb",
51
- "test/unit/remailer_interpreter_state_proxy_test.rb",
52
- "test/unit/remailer_interpreter_test.rb",
53
- "test/unit/remailer_test.rb"
45
+ "test/helper.rb",
46
+ "test/unit/remailer_connection_smtp_interpreter_test.rb",
47
+ "test/unit/remailer_connection_socks5_interpreter_test.rb",
48
+ "test/unit/remailer_connection_test.rb",
49
+ "test/unit/remailer_interpreter_state_proxy_test.rb",
50
+ "test/unit/remailer_interpreter_test.rb",
51
+ "test/unit/remailer_test.rb"
54
52
  ]
55
53
 
56
54
  if s.respond_to? :specification_version then
@@ -22,6 +22,24 @@ class AutomaticDelegate
22
22
  end
23
23
  end
24
24
 
25
+ class LineInterpreter < Remailer::Interpreter
26
+ attr_reader :lines
27
+
28
+ state :initialized do
29
+ enter do
30
+ @lines = [ ]
31
+ end
32
+ end
33
+
34
+ parse(/^.*?\r?\n/) do |data|
35
+ data.chomp
36
+ end
37
+
38
+ default do |line|
39
+ @lines << line
40
+ end
41
+ end
42
+
25
43
  class ExampleInterpreter < Remailer::Interpreter
26
44
  include TestTriggerHelper
27
45
 
@@ -65,7 +83,7 @@ end
65
83
 
66
84
  class RemailerInterpreterTest < Test::Unit::TestCase
67
85
  def test_default_state
68
- assert_equal [ :initialized, :terminated ], Remailer::Interpreter.states_defined
86
+ assert_equal [ :initialized, :terminated ], Remailer::Interpreter.states_defined.collect { |s| s.to_s }.sort.collect { |s| s.to_sym }
69
87
  assert_equal true, Remailer::Interpreter.state_defined?(:initialized)
70
88
  assert_equal true, Remailer::Interpreter.state_defined?(:terminated)
71
89
  assert_equal false, Remailer::Interpreter.state_defined?(:unknown)
@@ -121,6 +139,55 @@ class RemailerInterpreterTest < Test::Unit::TestCase
121
139
  assert_equal 'Stop message', interpreter.message
122
140
  assert_equal :terminated, interpreter.state
123
141
  end
142
+
143
+ def test_interpreter_can_process
144
+ interpreter = LineInterpreter.new
145
+
146
+ assert_equal [ ], interpreter.lines
147
+
148
+ line = "EXAMPLE LINE\n"
149
+
150
+ interpreter.process(line)
151
+
152
+ assert_equal 'EXAMPLE LINE', interpreter.lines[-1]
153
+ assert_equal '', line
154
+
155
+ line << "ANOTHER EXAMPLE LINE\r\n"
156
+
157
+ interpreter.process(line)
158
+
159
+ assert_equal 'ANOTHER EXAMPLE LINE', interpreter.lines[-1]
160
+ assert_equal '', line
161
+
162
+ line << "LINE ONE\r\nLINE TWO\r\n"
163
+
164
+ interpreter.process(line)
165
+
166
+ assert_equal 'LINE ONE', interpreter.lines[-2]
167
+ assert_equal 'LINE TWO', interpreter.lines[-1]
168
+ assert_equal '', line
169
+
170
+ line << "INCOMPLETE LINE"
171
+
172
+ interpreter.process(line)
173
+
174
+ assert_equal 'LINE TWO', interpreter.lines[-1]
175
+ assert_equal "INCOMPLETE LINE", line
176
+
177
+ line << "\r"
178
+
179
+ interpreter.process(line)
180
+
181
+ assert_equal 'LINE TWO', interpreter.lines[-1]
182
+ assert_equal "INCOMPLETE LINE\r", line
183
+
184
+ line << "\n"
185
+
186
+ interpreter.process(line)
187
+
188
+ assert_equal 'INCOMPLETE LINE', interpreter.lines[-1]
189
+ assert_equal '', line
190
+ end
124
191
 
125
192
  def test_default_handler_for_interpreter
126
193
  interpreter = ExampleInterpreter.new
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 6
9
- version: 0.3.6
8
+ - 8
9
+ version: 0.3.8
10
10
  platform: ruby
11
11
  authors:
12
12
  - Scott Tadman
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-17 00:00:00 -05:00
17
+ date: 2011-01-12 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
21
- description: EventMachine capable SMTP engine
21
+ description: EventMachine SMTP Mail User Agent
22
22
  email: scott@twg.ca
23
23
  executables: []
24
24
 
@@ -28,7 +28,6 @@ extra_rdoc_files:
28
28
  - README.rdoc
29
29
  files:
30
30
  - .document
31
- - .gitignore
32
31
  - README.rdoc
33
32
  - Rakefile
34
33
  - VERSION
@@ -52,8 +51,8 @@ homepage: http://github.com/twg/remailer
52
51
  licenses: []
53
52
 
54
53
  post_install_message:
55
- rdoc_options:
56
- - --charset=UTF-8
54
+ rdoc_options: []
55
+
57
56
  require_paths:
58
57
  - lib
59
58
  required_ruby_version: !ruby/object:Gem::Requirement
data/.gitignore DELETED
@@ -1,25 +0,0 @@
1
- *.gem
2
-
3
- config.rb
4
-
5
- ## MAC OS
6
- .DS_Store
7
-
8
- ## TEXTMATE
9
- *.tmproj
10
- tmtags
11
-
12
- ## EMACS
13
- *~
14
- \#*
15
- .\#*
16
-
17
- ## VIM
18
- *.swp
19
-
20
- ## PROJECT::GENERAL
21
- coverage
22
- rdoc
23
- pkg
24
-
25
- ## PROJECT::SPECIFIC