remailer 0.3.6 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
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