fakesmtpd 0.2.0 → 0.3.0
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/lib/fakesmtpd/server.rb +63 -70
- data/lib/fakesmtpd/version.rb +1 -1
- metadata +4 -4
data/lib/fakesmtpd/server.rb
CHANGED
@@ -26,6 +26,7 @@
|
|
26
26
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
27
|
|
28
28
|
require 'fileutils'
|
29
|
+
require 'gserver'
|
29
30
|
require 'json'
|
30
31
|
require 'logger'
|
31
32
|
require 'optparse'
|
@@ -33,48 +34,45 @@ require 'socket'
|
|
33
34
|
require 'thread'
|
34
35
|
|
35
36
|
module FakeSMTPd
|
36
|
-
class HTTPServer
|
37
|
-
attr_reader :server, :port, :smtpd
|
37
|
+
class HTTPServer < GServer
|
38
|
+
attr_reader :server, :port, :smtpd
|
38
39
|
|
39
40
|
def initialize(options = {})
|
40
41
|
@port = options.fetch(:port)
|
41
42
|
@smtpd = options.fetch(:smtpd)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
super(
|
44
|
+
@port,
|
45
|
+
options[:host] || '0.0.0.0',
|
46
|
+
options[:max_connections] || 4,
|
47
|
+
options[:logfile],
|
48
|
+
options[:audit] || !!ENV['FAKESMTPD_AUDIT'] || false,
|
49
|
+
options[:debug] || !!ENV['FAKESMTPD_DEBUG'] || false
|
50
|
+
)
|
47
51
|
end
|
48
52
|
|
49
|
-
def start
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
log.info "PID=#{$$} Thread=#{Thread.current.inspect}"
|
54
|
-
loop do
|
55
|
-
client = httpd.accept
|
56
|
-
begin
|
57
|
-
request_line = client.gets
|
58
|
-
path = request_line.split[1]
|
59
|
-
handle_client(request_line, path, client)
|
60
|
-
rescue => e
|
61
|
-
handle_500(path, client, e)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
53
|
+
def start(*args)
|
54
|
+
super(*args)
|
55
|
+
log "FakeSMTPd HTTP server serving on #{port}"
|
56
|
+
log "PID=#{$$} Thread=#{Thread.current.inspect}"
|
65
57
|
end
|
66
58
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
59
|
+
def stop(*args)
|
60
|
+
log "FakeSMTPd HTTP server stopping"
|
61
|
+
super(*args)
|
62
|
+
end
|
63
|
+
|
64
|
+
def serve(io)
|
65
|
+
request_line = io.gets
|
66
|
+
path = request_line.split[1]
|
67
|
+
handle_client(request_line, path, io)
|
68
|
+
rescue => e
|
69
|
+
handle_500(path, io, e)
|
72
70
|
end
|
73
71
|
|
74
72
|
private
|
75
73
|
|
76
74
|
def handle_client(request_line, path, client)
|
77
|
-
log
|
75
|
+
log request_line.chomp
|
78
76
|
case request_line
|
79
77
|
when /^GET \/ /
|
80
78
|
handle_get_root(path, client)
|
@@ -87,7 +85,6 @@ module FakeSMTPd
|
|
87
85
|
else
|
88
86
|
handle_404(path, client)
|
89
87
|
end
|
90
|
-
client.close
|
91
88
|
end
|
92
89
|
|
93
90
|
def handle_get_root(path, client)
|
@@ -184,8 +181,8 @@ module FakeSMTPd
|
|
184
181
|
end
|
185
182
|
end
|
186
183
|
|
187
|
-
class Server
|
188
|
-
VERSION = '0.
|
184
|
+
class Server < GServer
|
185
|
+
VERSION = '0.3.0'
|
189
186
|
USAGE = <<-EOU.gsub(/^ {6}/, '')
|
190
187
|
Usage: #{File.basename($0)} <smtp-port> <message-dir> [options]
|
191
188
|
|
@@ -195,9 +192,11 @@ module FakeSMTPd
|
|
195
192
|
transaction), the sender, recipients, and combined headers and body as
|
196
193
|
an array of strings.
|
197
194
|
|
195
|
+
Version: #{VERSION}
|
196
|
+
|
198
197
|
EOU
|
199
198
|
|
200
|
-
attr_reader :port, :message_dir, :
|
199
|
+
attr_reader :port, :message_dir, :logfile, :pidfile
|
201
200
|
attr_reader :messages
|
202
201
|
|
203
202
|
class << self
|
@@ -220,7 +219,7 @@ module FakeSMTPd
|
|
220
219
|
opts.on('-l LOGFILE', '--logfile LOGFILE',
|
221
220
|
'Optional file where all log messages will be written ' <<
|
222
221
|
'(default $stderr)') do |logfile|
|
223
|
-
options[:logfile] = logfile
|
222
|
+
options[:logfile] = File.open(logfile, 'a')
|
224
223
|
end
|
225
224
|
end.parse!(argv)
|
226
225
|
|
@@ -242,13 +241,13 @@ module FakeSMTPd
|
|
242
241
|
|
243
242
|
@httpd.start
|
244
243
|
@smtpd.start
|
245
|
-
|
244
|
+
@httpd.join && @smtpd.join
|
246
245
|
rescue Exception => e
|
247
|
-
if @httpd
|
248
|
-
@httpd.
|
246
|
+
if @httpd && !@httpd.stopped?
|
247
|
+
@httpd.stop
|
249
248
|
end
|
250
|
-
if @smtpd
|
251
|
-
@smtpd.
|
249
|
+
if @smtpd && !@smtpd.stopped?
|
250
|
+
@smtpd.stop
|
252
251
|
end
|
253
252
|
unless e.is_a?(Interrupt)
|
254
253
|
raise e
|
@@ -259,38 +258,32 @@ module FakeSMTPd
|
|
259
258
|
def initialize(options = {})
|
260
259
|
@port = options.fetch(:port)
|
261
260
|
@message_dir = options.fetch(:dir)
|
262
|
-
@pidfile = options[:pidfile]
|
263
|
-
@log = Logger.new(options[:logfile]).tap do |l|
|
264
|
-
l.formatter = proc do |severity, datetime, _, msg|
|
265
|
-
"[fakesmtpd-smtp] #{severity} #{datetime} - #{msg}\n"
|
266
|
-
end
|
267
|
-
end
|
261
|
+
@pidfile = options[:pidfile]
|
268
262
|
@messages = MessageStore.new(@message_dir)
|
263
|
+
|
264
|
+
super(
|
265
|
+
@port,
|
266
|
+
options[:host] || '0.0.0.0',
|
267
|
+
options[:max_connections] || 4,
|
268
|
+
options[:logfile],
|
269
|
+
options[:audit] || !!ENV['FAKESMTPD_AUDIT'] || false,
|
270
|
+
options[:debug] || !!ENV['FAKESMTPD_DEBUG'] || false
|
271
|
+
)
|
269
272
|
end
|
270
273
|
|
271
|
-
def start
|
272
|
-
|
273
|
-
|
274
|
-
log.info "FakeSMTPd SMTP server serving on #{port}, " <<
|
275
|
-
"writing messages to #{message_dir.inspect}"
|
276
|
-
log.info "PID=#{$$}, Thread=#{Thread.current.inspect}"
|
274
|
+
def start(*args)
|
275
|
+
super(*args)
|
276
|
+
if pidfile
|
277
277
|
File.open(pidfile, 'w') { |f| f.puts($$) }
|
278
|
-
|
279
|
-
loop do
|
280
|
-
begin
|
281
|
-
serve(smtpd.accept)
|
282
|
-
rescue => e
|
283
|
-
log.error "WAT: #{e.class.name} #{e.message}"
|
284
|
-
end
|
285
|
-
end
|
286
278
|
end
|
279
|
+
log "FakeSMTPd SMTP server serving on #{port}, writing messages to " <<
|
280
|
+
"#{message_dir.inspect}"
|
281
|
+
log "PID=#{$$} Thread=#{Thread.current.inspect}"
|
287
282
|
end
|
288
283
|
|
289
|
-
def
|
290
|
-
|
291
|
-
|
292
|
-
@server.kill
|
293
|
-
end
|
284
|
+
def stop(*args)
|
285
|
+
log "FakeSMTPd SMTP server stopping"
|
286
|
+
super(*args)
|
294
287
|
end
|
295
288
|
|
296
289
|
def serve(client)
|
@@ -311,17 +304,17 @@ module FakeSMTPd
|
|
311
304
|
|
312
305
|
client.puts '220 localhost fakesmtpd ready ESMTP'
|
313
306
|
helo = client.getline
|
314
|
-
log
|
307
|
+
log "#{client} Helo: #{helo.inspect}"
|
315
308
|
|
316
309
|
if helo =~ /^EHLO\s+/
|
317
|
-
log
|
310
|
+
log "#{client} Seen an EHLO"
|
318
311
|
client.puts '250-localhost only has this one extension'
|
319
312
|
client.puts '250 HELP'
|
320
313
|
end
|
321
314
|
|
322
315
|
from = client.getline
|
323
316
|
client.puts '250 OK'
|
324
|
-
log
|
317
|
+
log "#{client} From: #{from.inspect}"
|
325
318
|
|
326
319
|
recipients = []
|
327
320
|
loop do
|
@@ -332,7 +325,7 @@ module FakeSMTPd
|
|
332
325
|
client.puts '354 Lemme have it'
|
333
326
|
break
|
334
327
|
else
|
335
|
-
log
|
328
|
+
log "#{client} To: #{to.inspect}"
|
336
329
|
recipients << to
|
337
330
|
client.puts '250 OK'
|
338
331
|
end
|
@@ -343,14 +336,14 @@ module FakeSMTPd
|
|
343
336
|
line = client.getline
|
344
337
|
break if line.nil? || line == '.'
|
345
338
|
lines << line
|
346
|
-
log
|
339
|
+
log "#{client} + #{line}"
|
347
340
|
end
|
348
341
|
|
349
342
|
client.puts '250 OK'
|
350
343
|
client.gets
|
351
344
|
client.puts '221 Buhbye'
|
352
345
|
client.close
|
353
|
-
log
|
346
|
+
log "#{client} ding!"
|
354
347
|
|
355
348
|
record(client, from, recipients, lines)
|
356
349
|
end
|
data/lib/fakesmtpd/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fakesmtpd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -80,7 +80,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
80
|
version: '0'
|
81
81
|
segments:
|
82
82
|
- 0
|
83
|
-
hash:
|
83
|
+
hash: -2619994145312715398
|
84
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
85
|
none: false
|
86
86
|
requirements:
|
@@ -89,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
89
|
version: '0'
|
90
90
|
segments:
|
91
91
|
- 0
|
92
|
-
hash:
|
92
|
+
hash: -2619994145312715398
|
93
93
|
requirements: []
|
94
94
|
rubyforge_project:
|
95
95
|
rubygems_version: 1.8.23
|