Skip to content

Commit 78b087f

Browse files
authored
Merge pull request #34 from tmtm/add_mail_rcpt_params
add Net::SMTP::Address
2 parents e6a9fba + b84fc17 commit 78b087f

File tree

2 files changed

+81
-8
lines changed

2 files changed

+81
-8
lines changed

lib/net/smtp.rb

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,14 @@ def capable_starttls?
274274
capable?('STARTTLS')
275275
end
276276

277+
# true if the EHLO response contains +key+.
277278
def capable?(key)
278279
return nil unless @capabilities
279280
@capabilities[key] ? true : false
280281
end
281-
private :capable?
282+
283+
# The server capabilities by EHLO response
284+
attr_reader :capabilities
282285

283286
# true if server advertises AUTH PLAIN.
284287
# You cannot get valid value before opening SMTP session.
@@ -703,9 +706,9 @@ def do_finish
703706
# binary message with this method. +msgstr+ should include both
704707
# the message headers and body.
705708
#
706-
# +from_addr+ is a String representing the source mail address.
709+
# +from_addr+ is a String or Net::SMTP::Address representing the source mail address.
707710
#
708-
# +to_addr+ is a String or Strings or Array of Strings, representing
711+
# +to_addr+ is a String or Net::SMTP::Address or Array of them, representing
709712
# the destination mail address or addresses.
710713
#
711714
# === Example
@@ -716,6 +719,12 @@ def do_finish
716719
717720
# end
718721
#
722+
# Net::SMTP.start('smtp.example.com') do |smtp|
723+
# smtp.send_message msgstr,
724+
# Net::SMTP::Address.new('[email protected]', size: 12345),
725+
# Net::SMTP::Address.new('[email protected]', notify: :success)
726+
# end
727+
#
719728
# === Errors
720729
#
721730
# This method may raise:
@@ -752,9 +761,9 @@ def send_message(msgstr, from_addr, *to_addrs)
752761
#
753762
# === Parameters
754763
#
755-
# +from_addr+ is a String representing the source mail address.
764+
# +from_addr+ is a String or Net::SMTP::Address representing the source mail address.
756765
#
757-
# +to_addr+ is a String or Strings or Array of Strings, representing
766+
# +to_addr+ is a String or Net::SMTP::Address or Array of them, representing
758767
# the destination mail address or addresses.
759768
#
760769
# === Example
@@ -904,8 +913,10 @@ def ehlo(domain)
904913
getok("EHLO #{domain}")
905914
end
906915

916+
# +from_addr+ is +String+ or +Net::SMTP::Address+
907917
def mailfrom(from_addr)
908-
getok("MAIL FROM:<#{from_addr}>")
918+
addr = Address.new(from_addr)
919+
getok((["MAIL FROM:<#{addr.address}>"] + addr.parameters).join(' '))
909920
end
910921

911922
def rcptto_list(to_addrs)
@@ -916,7 +927,7 @@ def rcptto_list(to_addrs)
916927
begin
917928
rcptto addr
918929
rescue SMTPAuthenticationError
919-
unknown_users << addr.dump
930+
unknown_users << addr.to_s.dump
920931
else
921932
ok_users << addr
922933
end
@@ -929,8 +940,10 @@ def rcptto_list(to_addrs)
929940
ret
930941
end
931942

943+
# +to_addr+ is +String+ or +Net::SMTP::Address+
932944
def rcptto(to_addr)
933-
getok("RCPT TO:<#{to_addr}>")
945+
addr = Address.new(to_addr)
946+
getok((["RCPT TO:<#{addr.address}>"] + addr.parameters).join(' '))
934947
end
935948

936949
# This method sends a message.
@@ -1139,6 +1152,33 @@ def logging(msg)
11391152
@debug_output << msg + "\n" if @debug_output
11401153
end
11411154

1155+
# Address with parametres for MAIL or RCPT command
1156+
class Address
1157+
# mail address [String]
1158+
attr_reader :address
1159+
# paramters [Array<String>]
1160+
attr_reader :parameters
1161+
1162+
# :call-seq:
1163+
# initialize(address, parameter, ...)
1164+
#
1165+
# address +String+ or +Net::SMTP::Address+
1166+
# parameter +String+ or +Hash+
1167+
def initialize(address, *args, **kw_args)
1168+
if address.kind_of? Address
1169+
@address = address.address
1170+
@parameters = address.parameters
1171+
else
1172+
@address = address
1173+
@parameters = (args + [kw_args]).map{|param| Array(param)}.flatten(1).map{|param| Array(param).compact.join('=')}
1174+
end
1175+
end
1176+
1177+
def to_s
1178+
@address
1179+
end
1180+
end
1181+
11421182
end # class SMTP
11431183

11441184
SMTPSession = SMTP # :nodoc:

test/net/smtp/test_smtp.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ def test_esmtp
7070
assert_equal 'omg', smtp.esmtp?
7171
end
7272

73+
def test_server_capabilities
74+
port = fake_server_start(starttls: true)
75+
smtp = Net::SMTP.start('localhost', port, starttls: false)
76+
assert_equal({"STARTTLS"=>[], "AUTH"=>["PLAIN"]}, smtp.capabilities)
77+
assert_equal(true, smtp.capable?('STARTTLS'))
78+
assert_equal(false, smtp.capable?('SMTPUTF8'))
79+
smtp.finish
80+
end
81+
7382
def test_rset
7483
smtp = Net::SMTP.new 'localhost', 25
7584
smtp.instance_variable_set :@socket, FakeSocket.new
@@ -85,6 +94,15 @@ def test_mailfrom
8594
assert_equal "MAIL FROM:<[email protected]>\r\n", sock.write_io.string
8695
end
8796

97+
def test_mailfrom_with_address
98+
sock = FakeSocket.new
99+
smtp = Net::SMTP.new 'localhost', 25
100+
smtp.instance_variable_set :@socket, sock
101+
addr = Net::SMTP::Address.new("[email protected]", size: 12345)
102+
assert smtp.mailfrom(addr).success?
103+
assert_equal "MAIL FROM:<[email protected]> size=12345\r\n", sock.write_io.string
104+
end
105+
88106
def test_rcptto
89107
sock = FakeSocket.new
90108
smtp = Net::SMTP.new 'localhost', 25
@@ -93,6 +111,21 @@ def test_rcptto
93111
assert_equal "RCPT TO:<[email protected]>\r\n", sock.write_io.string
94112
end
95113

114+
def test_rcptto_with_address
115+
sock = FakeSocket.new
116+
smtp = Net::SMTP.new 'localhost', 25
117+
smtp.instance_variable_set :@socket, sock
118+
addr = Net::SMTP::Address.new("[email protected]", nofty: :failure)
119+
assert smtp.rcptto(addr).success?
120+
assert_equal "RCPT TO:<[email protected]> nofty=failure\r\n", sock.write_io.string
121+
end
122+
123+
def test_address
124+
a = Net::SMTP::Address.new('[email protected]', 'p0=123', {p1: 456}, p2: nil, p3: '789')
125+
assert_equal '[email protected]', a.address
126+
assert_equal ['p0=123', 'p1=456', 'p2', 'p3=789'], a.parameters
127+
end
128+
96129
def test_auth_plain
97130
sock = FakeSocket.new
98131
smtp = Net::SMTP.new 'localhost', 25

0 commit comments

Comments
 (0)