Class: FakeSMTPd::Server
- Inherits:
-
GServer
- Object
- GServer
- FakeSMTPd::Server
- Defined in:
- lib/fakesmtpd/server.rb
Constant Summary collapse
- VERSION =
'0.3.1'
- USAGE =
<<-EOU.gsub(/^ {6}/, '') Usage: #{File.basename($0)} <smtp-port> <message-dir> [options] The `<smtp-port>` argument will be incremented by 1 for the HTTP API port. The `<message-dir>` is where each SMTP transaction will be written as a JSON file containing the "smtp client id" (timestamp from beginning of SMTP transaction), the sender, recipients, and combined headers and body as an array of strings. Version: #{VERSION} EOU
Instance Attribute Summary collapse
-
#logfile ⇒ Object
readonly
Returns the value of attribute logfile.
-
#message_dir ⇒ Object
readonly
Returns the value of attribute message_dir.
-
#messages ⇒ Object
readonly
Returns the value of attribute messages.
-
#pidfile ⇒ Object
readonly
Returns the value of attribute pidfile.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(options = {}) ⇒ Server
constructor
A new instance of Server.
- #record(client, from, recipients, body) ⇒ Object
- #serve(client) ⇒ Object
- #start(*args) ⇒ Object
- #stop(*args) ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Server
Returns a new instance of Server.
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/fakesmtpd/server.rb', line 261 def initialize( = {}) @port = .fetch(:port) @message_dir = .fetch(:dir) @pidfile = [:pidfile] @messages = MessageStore.new(@message_dir) super( @port, [:host] || '0.0.0.0', [:max_connections] || 4, [:logfile], [:audit] || !!ENV['FAKESMTPD_AUDIT'] || false, [:debug] || !!ENV['FAKESMTPD_DEBUG'] || false ) end |
Instance Attribute Details
#logfile ⇒ Object (readonly)
Returns the value of attribute logfile.
202 203 204 |
# File 'lib/fakesmtpd/server.rb', line 202 def logfile @logfile end |
#message_dir ⇒ Object (readonly)
Returns the value of attribute message_dir.
202 203 204 |
# File 'lib/fakesmtpd/server.rb', line 202 def @message_dir end |
#messages ⇒ Object (readonly)
Returns the value of attribute messages.
203 204 205 |
# File 'lib/fakesmtpd/server.rb', line 203 def @messages end |
#pidfile ⇒ Object (readonly)
Returns the value of attribute pidfile.
202 203 204 |
# File 'lib/fakesmtpd/server.rb', line 202 def pidfile @pidfile end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
202 203 204 |
# File 'lib/fakesmtpd/server.rb', line 202 def port @port end |
Class Method Details
.main(argv = []) ⇒ Object
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/fakesmtpd/server.rb', line 206 def main(argv = []) = { pidfile: nil, logfile: $stderr.set_encoding('UTF-8'), } OptionParser.new do |opts| opts. = USAGE opts.on('--version', 'Show version and exit') do |*| puts "fakesmtpd #{FakeSMTPd::Server::VERSION}" exit 0 end opts.on('-p PIDFILE', '--pidfile PIDFILE', 'Optional file where process PID will be written') do |pidfile| [:pidfile] = pidfile end opts.on('-l LOGFILE', '--logfile LOGFILE', 'Optional file where all log messages will be written ' << '(default $stderr)') do |logfile| [:logfile] = File.open(logfile, 'a:UTF-8') end end.parse!(argv) unless argv.length == 2 abort USAGE end @smtpd = FakeSMTPd::Server.new( port: Integer(argv.fetch(0)), dir: argv.fetch(1), pidfile: [:pidfile], logfile: [:logfile], ) @httpd = FakeSMTPd::HTTPServer.new( port: Integer(argv.fetch(0)) + 1, smtpd: @smtpd, logfile: [:logfile], ) @httpd.start @smtpd.start @httpd.join && @smtpd.join rescue Exception => e if @httpd && !@httpd.stopped? @httpd.stop end if @smtpd && !@smtpd.stopped? @smtpd.stop end unless e.is_a?(Interrupt) raise e end end |
Instance Method Details
#record(client, from, recipients, body) ⇒ Object
356 357 358 359 360 |
# File 'lib/fakesmtpd/server.rb', line 356 def record(client, from, recipients, body) .store( client.client_id, from, recipients, body ) end |
#serve(client) ⇒ Object
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/fakesmtpd/server.rb', line 292 def serve(client) client.set_encoding('UTF-8') class << client attr_reader :client_id def getline line = gets line.chomp! unless line.nil? line end def to_s @client_id ||= Time.now.utc.strftime('%Y%m%d%H%M%S%N') "<smtp client #{@client_id}>" end end client.puts '220 localhost fakesmtpd ready ESMTP' helo = client.getline log "#{client} Helo: #{helo.inspect}" if helo =~ /^EHLO\s+/ log "#{client} Seen an EHLO" client.puts '250-localhost only has this one extension' client.puts '250 HELP' end from = client.getline client.puts '250 OK' log "#{client} From: #{from.inspect}" recipients = [] loop do to = client.getline break if to.nil? if to =~ /^DATA/ client.puts '354 Lemme have it' break else log "#{client} To: #{to.inspect}" recipients << to client.puts '250 OK' end end lines = [] loop do line = client.getline break if line.nil? || line == '.' lines << line log "#{client} + #{line}" end client.puts '250 OK' client.gets client.puts '221 Buhbye' client.close log "#{client} ding!" record(client, from, recipients, lines) end |
#start(*args) ⇒ Object
277 278 279 280 281 282 283 284 285 |
# File 'lib/fakesmtpd/server.rb', line 277 def start(*args) super(*args) if pidfile File.open(pidfile, 'w') { |f| f.puts($$) } end log "FakeSMTPd SMTP server serving on #{port}, writing messages to " << "#{.inspect}" log "PID=#{$$} Thread=#{Thread.current.inspect}" end |
#stop(*args) ⇒ Object
287 288 289 290 |
# File 'lib/fakesmtpd/server.rb', line 287 def stop(*args) log "FakeSMTPd SMTP server stopping" super(*args) end |