Skip to content
This repository has been archived by the owner on Mar 29, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2 from ackintosh/develop
Browse files Browse the repository at this point in the history
Add -f option
  • Loading branch information
ackintosh committed Mar 15, 2014
2 parents c207504 + ecd1c49 commit 9245b1a
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 26 deletions.
Empty file removed .pounder/.gitkeep
Empty file.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,22 @@ operation verification.

### start

$ bundle exec pounder {port}
$ bundle exec pounder [port]

If POP acceess to the host that started Pounder, you can get the mail
data that is prepared in advance.

It will not be deleted when you receive mail, you can repeat access.

`[port]` is optional.
If it is omitted, a free port will be used automatically by [Ackintosh::Net::EmptyPort](https://github.com/ackintosh/ackintosh-net-empty_port).

#### `-f` option

$ bundle exec pounder -f pounder@example.com

Pounder can change 'From' header to specified email address.

## Contributing

1. Fork it
Expand Down
9 changes: 6 additions & 3 deletions bin/pounder
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#!/usr/bin/env ruby

require 'pounder'
require "ackintosh/net/empty_port"
port = $*[0] || Ackintosh::Net::EmptyPort.find
require 'ackintosh/net/empty_port'
require 'optparse'

Pounder::Server.invoke(port.to_i)
options = ARGV.getopts('p:f:')
port = options['p'] || Ackintosh::Net::EmptyPort.find
from_address = options['f'] || nil
Pounder::Server.invoke(port: port.to_i, from_address: from_address)
18 changes: 10 additions & 8 deletions lib/pounder/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,29 @@ module Pounder
class Server
include Command

def self.invoke(port)
new.listen(port)
def self.invoke(options)
new.listen(options)
end

def listen(port)
server = TCPServer.new(port)
puts "#{self.class}##{__method__} port=#{port}"
def listen(options)
server = TCPServer.new(options[:port])
puts "#{self.class}##{__method__} port=#{options[:port]}"

maildir_path = "#{Dir::pwd}/.pounder"
puts "Maildir: #{maildir_path}"
maildir = Maildir.new(maildir_path)

puts "From: #{options[:from_address]}" if options[:from_address]

while true
Thread.fork(server.accept) do |sock|
p sock
service(sock, sock, maildir)
service(sock, sock, maildir, options)
end
end
end

def service(input, output, maildir)
def service(input, output, maildir, options)
@input = input
@output = output
print_line "+OK pounder"
Expand All @@ -35,7 +37,7 @@ def service(input, output, maildir)
next
end

__send__(cmd_name, maildir, args)
__send__(cmd_name, maildir: maildir, args: args, options: options)
end
end

Expand Down
27 changes: 15 additions & 12 deletions lib/pounder/server/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,48 @@
module Pounder
class Server
module Command
def cmd_STAT(maildir, args)
print_line "+OK #{maildir.size} #{maildir.total_octets}"
def cmd_STAT(params)
print_line "+OK #{params[:maildir].size} #{params[:maildir].total_octets}"
end

def cmd_LIST(maildir, args)
def cmd_LIST(params)
print_line "+OK"
maildir.messages.each do |m|
params[:maildir].messages.each do |m|
print_line "#{m.seq} #{m.octets}"
end
print_line "."
end

def cmd_USER(maildir, args)
def cmd_USER(params)
# nop.
print_line "+OK"
end

def cmd_PASS(maildir, args)
def cmd_PASS(params)
# nop.
print_line "+OK"
end

def cmd_DELE(maildir, args)
def cmd_DELE(params)
# nop.
print_line "+OK"
end

def cmd_QUIT(maildir, args)
def cmd_QUIT(params)
print_line "+OK"
terminate
end

def cmd_RETR(maildir, args)
message = maildir[args.first.to_i]
def cmd_RETR(params)
message = params[:maildir][params[:args].first.to_i]
print_line "+OK"
message.each_line do |line|
if line.match(/^Date: .*/) then
if line.match(/\ADate: .*/) then
# Outputs a Date header of the time it was run.
print_line_message "Date: #{DateTime.now.httpdate}"
print_line "Date: #{DateTime.now.httpdate}"
next
elsif (params[:options][:from_address] && line.match(/\AFrom: .*/)) then
print_line "From: \"#{params[:options][:from_address]}\" <#{params[:options][:from_address]}>"
next
end
print_line_message line
Expand Down
2 changes: 1 addition & 1 deletion lib/pounder/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Pounder
VERSION = "0.0.2"
VERSION = "0.0.3"
end
33 changes: 32 additions & 1 deletion spec/pounder/server/command_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,38 @@
output = double("TCPSocket")
output.should_receive(:print).with("+OK 100 10000\r\n")
@server.instance_variable_set(:@output, output)
@server.cmd_STAT(@maildir, [])
@server.cmd_STAT(maildir: @maildir, args: [])
end
end

describe "#cmd_QUIT" do
it "prints '+OK' and terminate the thread" do
output = double("TCPSocket")
output.should_receive(:print).with("+OK\r\n")
@server.instance_variable_set(:@output, output)
expect(@server).to receive(:terminate)
@server.send(:cmd_QUIT, maildir: @maildir, args: [])
end
end

shared_examples("no operation") do |cmd|
it "prints '+OK'" do
output = double("TCPSocket")
output.should_receive(:print).with("+OK\r\n")
@server.instance_variable_set(:@output, output)
@server.send(cmd, maildir: @maildir, args: [])
end
end

describe "#cmd_USER" do
it_behaves_like "no operation", :cmd_USER
end

describe "#cmd_PASS" do
it_behaves_like "no operation", :cmd_PASS
end

describe "#cmd_DELE" do
it_behaves_like "no operation", :cmd_DELE
end
end
20 changes: 20 additions & 0 deletions spec/pounder/server_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,24 @@
@server.print_line_message(".test")
end
end

describe "#read_cmd" do
context "@input.gets returns Command name only" do
it "returns Command name and empty array" do
input = double("TCPSocket")
input.should_receive(:gets).and_return("STAT")
@server.instance_variable_set(:@input, input)
expect(@server.read_cmd).to eq(["cmd_STAT", []])
end
end

context "@input.gets returns Command name and args" do
it "returns Command name and an array whose elements are the args" do
input = double("TCPSocket")
input.should_receive(:gets).and_return("RETR 2")
@server.instance_variable_set(:@input, input)
expect(@server.read_cmd).to eq(["cmd_RETR", ["2"]])
end
end
end
end

0 comments on commit 9245b1a

Please sign in to comment.