net-smtp 0.2.0 → 0.3.3
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.
- checksums.yaml +4 -4
- data/lib/net/smtp.rb +156 -56
- data/net-smtp.gemspec +9 -7
- metadata +21 -14
- data/.github/workflows/test.yml +0 -24
- data/.gitignore +0 -9
- data/Gemfile +0 -9
- data/NEWS.md +0 -44
- data/README.md +0 -97
- data/Rakefile +0 -10
- data/bin/console +0 -7
- data/bin/setup +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 314f553cc9e988f56b964e62836e95e323974b6a66c26e2f02d1e6a7cc08e886
|
4
|
+
data.tar.gz: 43a203a0622f49e2fb32a6c8bc0f644cb703e3bc3bc1f25aa114434c1a9cc8e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 486381bf1eee2cbd7cb4f12ca0253ee5b06fc2b1a012b3786bda9b30456c338c5de40889e639275cfcf22a83064d7c468aa06c8e21438adb1d1ab2133a3933eb
|
7
|
+
data.tar.gz: 97659f9e6505ea3aa10db92d5a99dc39d01ca55468ca28934b77061ccedd7ce74d8652927304ddf7fe4a21622e3572cca3bb92f19bae3a1b004bc7909783b530
|
data/lib/net/smtp.rb
CHANGED
@@ -18,11 +18,13 @@
|
|
18
18
|
#
|
19
19
|
|
20
20
|
require 'net/protocol'
|
21
|
-
require 'digest/md5'
|
22
|
-
require 'timeout'
|
23
21
|
begin
|
24
22
|
require 'openssl'
|
25
23
|
rescue LoadError
|
24
|
+
begin
|
25
|
+
require 'digest/md5'
|
26
|
+
rescue LoadError
|
27
|
+
end
|
26
28
|
end
|
27
29
|
|
28
30
|
module Net
|
@@ -31,6 +33,22 @@ module Net
|
|
31
33
|
module SMTPError
|
32
34
|
# This *class* is a module for backward compatibility.
|
33
35
|
# In later release, this module becomes a class.
|
36
|
+
|
37
|
+
attr_reader :response
|
38
|
+
|
39
|
+
def initialize(response, message: nil)
|
40
|
+
if response.is_a?(::Net::SMTP::Response)
|
41
|
+
@response = response
|
42
|
+
@message = message
|
43
|
+
else
|
44
|
+
@response = nil
|
45
|
+
@message = message || response
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def message
|
50
|
+
@message || response.message
|
51
|
+
end
|
34
52
|
end
|
35
53
|
|
36
54
|
# Represents an SMTP authentication error.
|
@@ -168,7 +186,7 @@ module Net
|
|
168
186
|
# user: 'Your Account', secret: 'Your Password', authtype: :cram_md5)
|
169
187
|
#
|
170
188
|
class SMTP < Protocol
|
171
|
-
VERSION = "0.
|
189
|
+
VERSION = "0.3.3"
|
172
190
|
|
173
191
|
Revision = %q$Revision$.split[1]
|
174
192
|
|
@@ -191,12 +209,9 @@ module Net
|
|
191
209
|
alias default_ssl_port default_tls_port
|
192
210
|
end
|
193
211
|
|
194
|
-
def SMTP.default_ssl_context(
|
212
|
+
def SMTP.default_ssl_context(ssl_context_params = nil)
|
195
213
|
context = OpenSSL::SSL::SSLContext.new
|
196
|
-
context.
|
197
|
-
store = OpenSSL::X509::Store.new
|
198
|
-
store.set_default_paths
|
199
|
-
context.cert_store = store
|
214
|
+
context.set_params(ssl_context_params ? ssl_context_params : {})
|
200
215
|
context
|
201
216
|
end
|
202
217
|
|
@@ -207,11 +222,23 @@ module Net
|
|
207
222
|
# server. +port+ is the port to connect to; it defaults to
|
208
223
|
# port 25.
|
209
224
|
#
|
225
|
+
# If +tls+ is true, enable TLS. The default is false.
|
226
|
+
# If +starttls+ is :always, enable STARTTLS, if +:auto+, use STARTTLS when the server supports it,
|
227
|
+
# if false, disable STARTTLS.
|
228
|
+
#
|
229
|
+
# If +tls_verify+ is true, verify the server's certificate. The default is true.
|
230
|
+
# If the hostname in the server certificate is different from +address+,
|
231
|
+
# it can be specified with +tls_hostname+.
|
232
|
+
#
|
233
|
+
# Additional SSLContext params can be added to +ssl_context_params+ hash argument and are passed to
|
234
|
+
# +OpenSSL::SSL::SSLContext#set_params+
|
235
|
+
#
|
236
|
+
# +tls_verify: true+ is equivalent to +ssl_context_params: { verify_mode: OpenSSL::SSL::VERIFY_PEER }+.
|
210
237
|
# This method does not open the TCP connection. You can use
|
211
238
|
# SMTP.start instead of SMTP.new if you want to do everything
|
212
239
|
# at once. Otherwise, follow SMTP.new with SMTP#start.
|
213
240
|
#
|
214
|
-
def initialize(address, port = nil)
|
241
|
+
def initialize(address, port = nil, tls: false, starttls: :auto, tls_verify: true, tls_hostname: nil, ssl_context_params: nil)
|
215
242
|
@address = address
|
216
243
|
@port = (port || SMTP.default_port)
|
217
244
|
@esmtp = true
|
@@ -222,12 +249,24 @@ module Net
|
|
222
249
|
@read_timeout = 60
|
223
250
|
@error_occurred = false
|
224
251
|
@debug_output = nil
|
225
|
-
@tls =
|
226
|
-
@starttls =
|
252
|
+
@tls = tls
|
253
|
+
@starttls = starttls
|
227
254
|
@ssl_context_tls = nil
|
228
255
|
@ssl_context_starttls = nil
|
256
|
+
@tls_verify = tls_verify
|
257
|
+
@tls_hostname = tls_hostname
|
258
|
+
@ssl_context_params = ssl_context_params
|
229
259
|
end
|
230
260
|
|
261
|
+
# If +true+, verify th server's certificate.
|
262
|
+
attr_accessor :tls_verify
|
263
|
+
|
264
|
+
# The hostname for verifying hostname in the server certificatate.
|
265
|
+
attr_accessor :tls_hostname
|
266
|
+
|
267
|
+
# Hash for additional SSLContext parameters.
|
268
|
+
attr_accessor :ssl_context_params
|
269
|
+
|
231
270
|
# Provide human-readable stringification of class state.
|
232
271
|
def inspect
|
233
272
|
"#<#{self.class} #{@address}:#{@port} started=#{@started}>"
|
@@ -251,11 +290,14 @@ module Net
|
|
251
290
|
capable?('STARTTLS')
|
252
291
|
end
|
253
292
|
|
293
|
+
# true if the EHLO response contains +key+.
|
254
294
|
def capable?(key)
|
255
295
|
return nil unless @capabilities
|
256
296
|
@capabilities[key] ? true : false
|
257
297
|
end
|
258
|
-
|
298
|
+
|
299
|
+
# The server capabilities by EHLO response
|
300
|
+
attr_reader :capabilities
|
259
301
|
|
260
302
|
# true if server advertises AUTH PLAIN.
|
261
303
|
# You cannot get valid value before opening SMTP session.
|
@@ -301,7 +343,7 @@ module Net
|
|
301
343
|
# this object. Must be called before the connection is established
|
302
344
|
# to have any effect. +context+ is a OpenSSL::SSL::SSLContext object.
|
303
345
|
def enable_tls(context = nil)
|
304
|
-
raise 'openssl library not installed' unless defined?(OpenSSL)
|
346
|
+
raise 'openssl library not installed' unless defined?(OpenSSL::VERSION)
|
305
347
|
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls == :always
|
306
348
|
@tls = true
|
307
349
|
@ssl_context_tls = context
|
@@ -338,7 +380,7 @@ module Net
|
|
338
380
|
# Enables SMTP/TLS (STARTTLS) for this object.
|
339
381
|
# +context+ is a OpenSSL::SSL::SSLContext object.
|
340
382
|
def enable_starttls(context = nil)
|
341
|
-
raise 'openssl library not installed' unless defined?(OpenSSL)
|
383
|
+
raise 'openssl library not installed' unless defined?(OpenSSL::VERSION)
|
342
384
|
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
|
343
385
|
@starttls = :always
|
344
386
|
@ssl_context_starttls = context
|
@@ -347,7 +389,7 @@ module Net
|
|
347
389
|
# Enables SMTP/TLS (STARTTLS) for this object if server accepts.
|
348
390
|
# +context+ is a OpenSSL::SSL::SSLContext object.
|
349
391
|
def enable_starttls_auto(context = nil)
|
350
|
-
raise 'openssl library not installed' unless defined?(OpenSSL)
|
392
|
+
raise 'openssl library not installed' unless defined?(OpenSSL::VERSION)
|
351
393
|
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
|
352
394
|
@starttls = :auto
|
353
395
|
@ssl_context_starttls = context
|
@@ -409,14 +451,14 @@ module Net
|
|
409
451
|
|
410
452
|
#
|
411
453
|
# :call-seq:
|
412
|
-
# start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... }
|
454
|
+
# start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls: false, starttls: :auto, tls_verify: true, tls_hostname: nil, ssl_context_params: nil) { |smtp| ... }
|
413
455
|
# start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
|
414
456
|
#
|
415
457
|
# Creates a new Net::SMTP object and connects to the server.
|
416
458
|
#
|
417
459
|
# This method is equivalent to:
|
418
460
|
#
|
419
|
-
# Net::SMTP.new(address, port).start(helo: helo_domain, user: account, secret: password, authtype: authtype, tls_verify: flag, tls_hostname: hostname)
|
461
|
+
# Net::SMTP.new(address, port).start(helo: helo_domain, user: account, secret: password, authtype: authtype, tls_verify: flag, tls_hostname: hostname, ssl_context_params: nil)
|
420
462
|
#
|
421
463
|
# === Example
|
422
464
|
#
|
@@ -446,10 +488,20 @@ module Net
|
|
446
488
|
# or other authentication token; and +authtype+ is the authentication
|
447
489
|
# type, one of :plain, :login, or :cram_md5. See the discussion of
|
448
490
|
# SMTP Authentication in the overview notes.
|
491
|
+
#
|
492
|
+
# If +tls+ is true, enable TLS. The default is false.
|
493
|
+
# If +starttls+ is :always, enable STARTTLS, if +:auto+, use STARTTLS when the server supports it,
|
494
|
+
# if false, disable STARTTLS.
|
495
|
+
#
|
449
496
|
# If +tls_verify+ is true, verify the server's certificate. The default is true.
|
450
497
|
# If the hostname in the server certificate is different from +address+,
|
451
498
|
# it can be specified with +tls_hostname+.
|
452
499
|
#
|
500
|
+
# Additional SSLContext params can be added to +ssl_context_params+ hash argument and are passed to
|
501
|
+
# +OpenSSL::SSL::SSLContext#set_params+
|
502
|
+
#
|
503
|
+
# +tls_verify: true+ is equivalent to +ssl_context_params: { verify_mode: OpenSSL::SSL::VERIFY_PEER }+.
|
504
|
+
#
|
453
505
|
# === Errors
|
454
506
|
#
|
455
507
|
# This method may raise:
|
@@ -465,14 +517,15 @@ module Net
|
|
465
517
|
#
|
466
518
|
def SMTP.start(address, port = nil, *args, helo: nil,
|
467
519
|
user: nil, secret: nil, password: nil, authtype: nil,
|
468
|
-
|
520
|
+
tls: false, starttls: :auto,
|
521
|
+
tls_verify: true, tls_hostname: nil, ssl_context_params: nil,
|
469
522
|
&block)
|
470
523
|
raise ArgumentError, "wrong number of arguments (given #{args.size + 2}, expected 1..6)" if args.size > 4
|
471
524
|
helo ||= args[0] || 'localhost'
|
472
525
|
user ||= args[1]
|
473
526
|
secret ||= password || args[2]
|
474
527
|
authtype ||= args[3]
|
475
|
-
new(address, port).start(helo: helo, user: user, secret: secret, authtype: authtype,
|
528
|
+
new(address, port, tls: tls, starttls: starttls, tls_verify: tls_verify, tls_hostname: tls_hostname, ssl_context_params: ssl_context_params).start(helo: helo, user: user, secret: secret, authtype: authtype, &block)
|
476
529
|
end
|
477
530
|
|
478
531
|
# +true+ if the SMTP session has been started.
|
@@ -482,7 +535,7 @@ module Net
|
|
482
535
|
|
483
536
|
#
|
484
537
|
# :call-seq:
|
485
|
-
# start(helo: 'localhost', user: nil, secret: nil, authtype: nil
|
538
|
+
# start(helo: 'localhost', user: nil, secret: nil, authtype: nil) { |smtp| ... }
|
486
539
|
# start(helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
|
487
540
|
#
|
488
541
|
# Opens a TCP connection and starts the SMTP session.
|
@@ -497,9 +550,6 @@ module Net
|
|
497
550
|
# the type of authentication to attempt; it must be one of
|
498
551
|
# :login, :plain, and :cram_md5. See the notes on SMTP Authentication
|
499
552
|
# in the overview.
|
500
|
-
# If +tls_verify+ is true, verify the server's certificate. The default is true.
|
501
|
-
# If the hostname in the server certificate is different from +address+,
|
502
|
-
# it can be specified with +tls_hostname+.
|
503
553
|
#
|
504
554
|
# === Block Usage
|
505
555
|
#
|
@@ -538,20 +588,24 @@ module Net
|
|
538
588
|
# * Net::ReadTimeout
|
539
589
|
# * IOError
|
540
590
|
#
|
541
|
-
def start(*args, helo: nil,
|
542
|
-
user: nil, secret: nil, password: nil, authtype: nil, tls_verify: true, tls_hostname: nil)
|
591
|
+
def start(*args, helo: nil, user: nil, secret: nil, password: nil, authtype: nil)
|
543
592
|
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..4)" if args.size > 4
|
544
593
|
helo ||= args[0] || 'localhost'
|
545
594
|
user ||= args[1]
|
546
595
|
secret ||= password || args[2]
|
547
596
|
authtype ||= args[3]
|
548
|
-
if
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
597
|
+
if defined?(OpenSSL::VERSION)
|
598
|
+
ssl_context_params = @ssl_context_params || {}
|
599
|
+
unless ssl_context_params.has_key?(:verify_mode)
|
600
|
+
ssl_context_params[:verify_mode] = @tls_verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
601
|
+
end
|
602
|
+
if @tls && @ssl_context_tls.nil?
|
603
|
+
@ssl_context_tls = SMTP.default_ssl_context(ssl_context_params)
|
604
|
+
end
|
605
|
+
if @starttls && @ssl_context_starttls.nil?
|
606
|
+
@ssl_context_starttls = SMTP.default_ssl_context(ssl_context_params)
|
607
|
+
end
|
553
608
|
end
|
554
|
-
@tls_hostname = tls_hostname
|
555
609
|
if block_given?
|
556
610
|
begin
|
557
611
|
do_start helo, user, secret, authtype
|
@@ -574,8 +628,23 @@ module Net
|
|
574
628
|
|
575
629
|
private
|
576
630
|
|
631
|
+
def digest_class
|
632
|
+
@digest_class ||= if defined?(OpenSSL::Digest)
|
633
|
+
OpenSSL::Digest
|
634
|
+
elsif defined?(::Digest)
|
635
|
+
::Digest
|
636
|
+
else
|
637
|
+
raise '"openssl" or "digest" library is required'
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
577
641
|
def tcp_socket(address, port)
|
578
|
-
|
642
|
+
begin
|
643
|
+
Socket.tcp address, port, nil, nil, connect_timeout: @open_timeout
|
644
|
+
rescue Errno::ETIMEDOUT #raise Net:OpenTimeout instead for compatibility with previous versions
|
645
|
+
raise Net::OpenTimeout, "Timeout to open TCP connection to "\
|
646
|
+
"#{address}:#{port} (exceeds #{@open_timeout} seconds)"
|
647
|
+
end
|
579
648
|
end
|
580
649
|
|
581
650
|
def do_start(helo_domain, user, secret, authtype)
|
@@ -584,17 +653,14 @@ module Net
|
|
584
653
|
check_auth_method(authtype || DEFAULT_AUTH_TYPE)
|
585
654
|
check_auth_args user, secret
|
586
655
|
end
|
587
|
-
s =
|
588
|
-
tcp_socket(@address, @port)
|
589
|
-
end
|
656
|
+
s = tcp_socket(@address, @port)
|
590
657
|
logging "Connection opened: #{@address}:#{@port}"
|
591
658
|
@socket = new_internet_message_io(tls? ? tlsconnect(s, @ssl_context_tls) : s)
|
592
659
|
check_response critical { recv_response() }
|
593
660
|
do_helo helo_domain
|
594
661
|
if ! tls? and (starttls_always? or (capable_starttls? and starttls_auto?))
|
595
662
|
unless capable_starttls?
|
596
|
-
raise SMTPUnsupportedCommand,
|
597
|
-
"STARTTLS is not supported on this server"
|
663
|
+
raise SMTPUnsupportedCommand, "STARTTLS is not supported on this server"
|
598
664
|
end
|
599
665
|
starttls
|
600
666
|
@socket = new_internet_message_io(tlsconnect(s, @ssl_context_starttls))
|
@@ -620,11 +686,8 @@ module Net
|
|
620
686
|
s = ssl_socket(s, context)
|
621
687
|
logging "TLS connection started"
|
622
688
|
s.sync_close = true
|
623
|
-
s.hostname = @tls_hostname || @address
|
689
|
+
s.hostname = @tls_hostname || @address
|
624
690
|
ssl_socket_connect(s, @open_timeout)
|
625
|
-
if context.verify_mode && context.verify_mode != OpenSSL::SSL::VERIFY_NONE
|
626
|
-
s.post_connection_check(@tls_hostname || @address)
|
627
|
-
end
|
628
691
|
verified = true
|
629
692
|
s
|
630
693
|
ensure
|
@@ -669,9 +732,9 @@ module Net
|
|
669
732
|
# binary message with this method. +msgstr+ should include both
|
670
733
|
# the message headers and body.
|
671
734
|
#
|
672
|
-
# +from_addr+ is a String representing the source mail address.
|
735
|
+
# +from_addr+ is a String or Net::SMTP::Address representing the source mail address.
|
673
736
|
#
|
674
|
-
# +to_addr+ is a String or
|
737
|
+
# +to_addr+ is a String or Net::SMTP::Address or Array of them, representing
|
675
738
|
# the destination mail address or addresses.
|
676
739
|
#
|
677
740
|
# === Example
|
@@ -682,6 +745,12 @@ module Net
|
|
682
745
|
# ['dest@example.com', 'dest2@example.com']
|
683
746
|
# end
|
684
747
|
#
|
748
|
+
# Net::SMTP.start('smtp.example.com') do |smtp|
|
749
|
+
# smtp.send_message msgstr,
|
750
|
+
# Net::SMTP::Address.new('from@example.com', size: 12345),
|
751
|
+
# Net::SMTP::Address.new('dest@example.com', notify: :success)
|
752
|
+
# end
|
753
|
+
#
|
685
754
|
# === Errors
|
686
755
|
#
|
687
756
|
# This method may raise:
|
@@ -718,9 +787,9 @@ module Net
|
|
718
787
|
#
|
719
788
|
# === Parameters
|
720
789
|
#
|
721
|
-
# +from_addr+ is a String representing the source mail address.
|
790
|
+
# +from_addr+ is a String or Net::SMTP::Address representing the source mail address.
|
722
791
|
#
|
723
|
-
# +to_addr+ is a String or
|
792
|
+
# +to_addr+ is a String or Net::SMTP::Address or Array of them, representing
|
724
793
|
# the destination mail address or addresses.
|
725
794
|
#
|
726
795
|
# === Example
|
@@ -765,7 +834,7 @@ module Net
|
|
765
834
|
def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)
|
766
835
|
check_auth_method authtype
|
767
836
|
check_auth_args user, secret
|
768
|
-
|
837
|
+
public_send auth_method(authtype), user, secret
|
769
838
|
end
|
770
839
|
|
771
840
|
def auth_plain(user, secret)
|
@@ -831,14 +900,14 @@ module Net
|
|
831
900
|
|
832
901
|
# CRAM-MD5: [RFC2195]
|
833
902
|
def cram_md5_response(secret, challenge)
|
834
|
-
tmp =
|
835
|
-
|
903
|
+
tmp = digest_class::MD5.digest(cram_secret(secret, IMASK) + challenge)
|
904
|
+
digest_class::MD5.hexdigest(cram_secret(secret, OMASK) + tmp)
|
836
905
|
end
|
837
906
|
|
838
907
|
CRAM_BUFSIZE = 64
|
839
908
|
|
840
909
|
def cram_secret(secret, mask)
|
841
|
-
secret =
|
910
|
+
secret = digest_class::MD5.digest(secret) if secret.size > CRAM_BUFSIZE
|
842
911
|
buf = secret.ljust(CRAM_BUFSIZE, "\0")
|
843
912
|
0.upto(buf.size - 1) do |i|
|
844
913
|
buf[i] = (buf[i].ord ^ mask).chr
|
@@ -870,8 +939,10 @@ module Net
|
|
870
939
|
getok("EHLO #{domain}")
|
871
940
|
end
|
872
941
|
|
942
|
+
# +from_addr+ is +String+ or +Net::SMTP::Address+
|
873
943
|
def mailfrom(from_addr)
|
874
|
-
|
944
|
+
addr = Address.new(from_addr)
|
945
|
+
getok((["MAIL FROM:<#{addr.address}>"] + addr.parameters).join(' '))
|
875
946
|
end
|
876
947
|
|
877
948
|
def rcptto_list(to_addrs)
|
@@ -882,7 +953,7 @@ module Net
|
|
882
953
|
begin
|
883
954
|
rcptto addr
|
884
955
|
rescue SMTPAuthenticationError
|
885
|
-
unknown_users << addr.dump
|
956
|
+
unknown_users << addr.to_s.dump
|
886
957
|
else
|
887
958
|
ok_users << addr
|
888
959
|
end
|
@@ -895,8 +966,10 @@ module Net
|
|
895
966
|
ret
|
896
967
|
end
|
897
968
|
|
969
|
+
# +to_addr+ is +String+ or +Net::SMTP::Address+
|
898
970
|
def rcptto(to_addr)
|
899
|
-
|
971
|
+
addr = Address.new(to_addr)
|
972
|
+
getok((["RCPT TO:<#{addr.address}>"] + addr.parameters).join(' '))
|
900
973
|
end
|
901
974
|
|
902
975
|
# This method sends a message.
|
@@ -1000,25 +1073,25 @@ module Net
|
|
1000
1073
|
|
1001
1074
|
def check_response(res)
|
1002
1075
|
unless res.success?
|
1003
|
-
raise res.exception_class
|
1076
|
+
raise res.exception_class.new(res)
|
1004
1077
|
end
|
1005
1078
|
end
|
1006
1079
|
|
1007
1080
|
def check_continue(res)
|
1008
1081
|
unless res.continue?
|
1009
|
-
raise SMTPUnknownError, "could not get 3xx (#{res.status}: #{res.string})"
|
1082
|
+
raise SMTPUnknownError.new(res, message: "could not get 3xx (#{res.status}: #{res.string})")
|
1010
1083
|
end
|
1011
1084
|
end
|
1012
1085
|
|
1013
1086
|
def check_auth_response(res)
|
1014
1087
|
unless res.success?
|
1015
|
-
raise SMTPAuthenticationError
|
1088
|
+
raise SMTPAuthenticationError.new(res)
|
1016
1089
|
end
|
1017
1090
|
end
|
1018
1091
|
|
1019
1092
|
def check_auth_continue(res)
|
1020
1093
|
unless res.continue?
|
1021
|
-
raise res.exception_class
|
1094
|
+
raise res.exception_class.new(res)
|
1022
1095
|
end
|
1023
1096
|
end
|
1024
1097
|
|
@@ -1105,6 +1178,33 @@ module Net
|
|
1105
1178
|
@debug_output << msg + "\n" if @debug_output
|
1106
1179
|
end
|
1107
1180
|
|
1181
|
+
# Address with parametres for MAIL or RCPT command
|
1182
|
+
class Address
|
1183
|
+
# mail address [String]
|
1184
|
+
attr_reader :address
|
1185
|
+
# parameters [Array<String>]
|
1186
|
+
attr_reader :parameters
|
1187
|
+
|
1188
|
+
# :call-seq:
|
1189
|
+
# initialize(address, parameter, ...)
|
1190
|
+
#
|
1191
|
+
# address +String+ or +Net::SMTP::Address+
|
1192
|
+
# parameter +String+ or +Hash+
|
1193
|
+
def initialize(address, *args, **kw_args)
|
1194
|
+
if address.kind_of? Address
|
1195
|
+
@address = address.address
|
1196
|
+
@parameters = address.parameters
|
1197
|
+
else
|
1198
|
+
@address = address
|
1199
|
+
@parameters = (args + [kw_args]).map{|param| Array(param)}.flatten(1).map{|param| Array(param).compact.join('=')}
|
1200
|
+
end
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
def to_s
|
1204
|
+
@address
|
1205
|
+
end
|
1206
|
+
end
|
1207
|
+
|
1108
1208
|
end # class SMTP
|
1109
1209
|
|
1110
1210
|
SMTPSession = SMTP # :nodoc:
|
data/net-smtp.gemspec
CHANGED
@@ -16,16 +16,18 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.summary = %q{Simple Mail Transfer Protocol client library for Ruby.}
|
17
17
|
spec.description = %q{Simple Mail Transfer Protocol client library for Ruby.}
|
18
18
|
spec.homepage = "https://github.com/ruby/net-smtp"
|
19
|
-
spec.
|
20
|
-
spec.required_ruby_version = ">= 2.
|
19
|
+
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
20
|
+
spec.required_ruby_version = ">= 2.6.0"
|
21
21
|
|
22
22
|
spec.metadata["homepage_uri"] = spec.homepage
|
23
23
|
spec.metadata["source_code_uri"] = spec.homepage
|
24
24
|
|
25
|
-
spec.files =
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
spec.files = %w[
|
26
|
+
LICENSE.txt
|
27
|
+
lib/net/smtp.rb
|
28
|
+
net-smtp.gemspec
|
29
|
+
]
|
30
30
|
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_dependency "net-protocol"
|
31
33
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-smtp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yukihiro Matsumoto
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2022-10-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: net-protocol
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: Simple Mail Transfer Protocol client library for Ruby.
|
14
28
|
email:
|
15
29
|
- matz@ruby-lang.org
|
@@ -17,19 +31,12 @@ executables: []
|
|
17
31
|
extensions: []
|
18
32
|
extra_rdoc_files: []
|
19
33
|
files:
|
20
|
-
- ".github/workflows/test.yml"
|
21
|
-
- ".gitignore"
|
22
|
-
- Gemfile
|
23
34
|
- LICENSE.txt
|
24
|
-
- NEWS.md
|
25
|
-
- README.md
|
26
|
-
- Rakefile
|
27
|
-
- bin/console
|
28
|
-
- bin/setup
|
29
35
|
- lib/net/smtp.rb
|
30
36
|
- net-smtp.gemspec
|
31
37
|
homepage: https://github.com/ruby/net-smtp
|
32
38
|
licenses:
|
39
|
+
- Ruby
|
33
40
|
- BSD-2-Clause
|
34
41
|
metadata:
|
35
42
|
homepage_uri: https://github.com/ruby/net-smtp
|
@@ -42,14 +49,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
49
|
requirements:
|
43
50
|
- - ">="
|
44
51
|
- !ruby/object:Gem::Version
|
45
|
-
version: 2.
|
52
|
+
version: 2.6.0
|
46
53
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
54
|
requirements:
|
48
55
|
- - ">="
|
49
56
|
- !ruby/object:Gem::Version
|
50
57
|
version: '0'
|
51
58
|
requirements: []
|
52
|
-
rubygems_version: 3.
|
59
|
+
rubygems_version: 3.4.0.dev
|
53
60
|
signing_key:
|
54
61
|
specification_version: 4
|
55
62
|
summary: Simple Mail Transfer Protocol client library for Ruby.
|
data/.github/workflows/test.yml
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
name: test
|
2
|
-
|
3
|
-
on: [push, pull_request]
|
4
|
-
|
5
|
-
jobs:
|
6
|
-
build:
|
7
|
-
name: build (${{ matrix.ruby }} / ${{ matrix.os }})
|
8
|
-
strategy:
|
9
|
-
matrix:
|
10
|
-
ruby: [ 2.7, 2.6, 2.5, head ]
|
11
|
-
os: [ ubuntu-latest, macos-latest ]
|
12
|
-
runs-on: ${{ matrix.os }}
|
13
|
-
steps:
|
14
|
-
- uses: actions/checkout@master
|
15
|
-
- name: Set up Ruby
|
16
|
-
uses: ruby/setup-ruby@v1
|
17
|
-
with:
|
18
|
-
ruby-version: ${{ matrix.ruby }}
|
19
|
-
- name: Install dependencies
|
20
|
-
run: |
|
21
|
-
gem install bundler --no-document
|
22
|
-
bundle install
|
23
|
-
- name: Run test
|
24
|
-
run: rake test
|
data/.gitignore
DELETED
data/Gemfile
DELETED
data/NEWS.md
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
# NEWS
|
2
|
-
|
3
|
-
## Version 0.2.0 (2020-11-15)
|
4
|
-
|
5
|
-
### Incompatible changes
|
6
|
-
|
7
|
-
* Verify the server's certificate by default.
|
8
|
-
If you don't want verification, specify `start(tls_verify: false)`.
|
9
|
-
<https://github.com/ruby/net-smtp/pull/12>
|
10
|
-
|
11
|
-
* Use STARTTLS by default if possible.
|
12
|
-
If you don't want starttls, specify:
|
13
|
-
```
|
14
|
-
smtp = Net::SMTP.new(hostname, port)
|
15
|
-
smtp.disable_starttls
|
16
|
-
smtp.start do |s|
|
17
|
-
s.send_message ....
|
18
|
-
end
|
19
|
-
```
|
20
|
-
<https://github.com/ruby/net-smtp/pull/9>
|
21
|
-
|
22
|
-
### Improvements
|
23
|
-
|
24
|
-
* Net::SMTP.start and Net::SMTP#start arguments are keyword arguments.
|
25
|
-
```
|
26
|
-
start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil) { |smtp| ... }
|
27
|
-
```
|
28
|
-
`password` is an alias of `secret`.
|
29
|
-
<https://github.com/ruby/net-smtp/pull/7>
|
30
|
-
|
31
|
-
* Add `tls_hostname` parameter to `start()`.
|
32
|
-
If you want to use a different hostname than the certificate for the connection, you can specify the certificate hostname with `tls_hostname`.
|
33
|
-
<https://github.com/ruby/net-smtp/pull/14>
|
34
|
-
|
35
|
-
* Add SNI support to net/smtp <https://github.com/ruby/net-smtp/pull/4>
|
36
|
-
|
37
|
-
### Fixes
|
38
|
-
|
39
|
-
* enable_starttls before disable_tls causes an error. <https://github.com/ruby/net-smtp/pull/10>
|
40
|
-
* TLS should not check the hostname when verify_mode is disabled. <https://github.com/ruby/net-smtp/pull/6>
|
41
|
-
|
42
|
-
## Version 0.1.0 (2019-12-03)
|
43
|
-
|
44
|
-
This is the first release of net-smtp gem.
|
data/README.md
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
# Net::SMTP
|
2
|
-
|
3
|
-
This library provides functionality to send internet mail via SMTP, the Simple Mail Transfer Protocol.
|
4
|
-
|
5
|
-
For details of SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt).
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
Add this line to your application's Gemfile:
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
gem 'net-smtp'
|
13
|
-
```
|
14
|
-
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install net-smtp
|
22
|
-
|
23
|
-
## Usage
|
24
|
-
|
25
|
-
### Sending Messages
|
26
|
-
|
27
|
-
You must open a connection to an SMTP server before sending messages.
|
28
|
-
The first argument is the address of your SMTP server, and the second
|
29
|
-
argument is the port number. Using SMTP.start with a block is the simplest
|
30
|
-
way to do this. This way, the SMTP connection is closed automatically
|
31
|
-
after the block is executed.
|
32
|
-
|
33
|
-
```ruby
|
34
|
-
require 'net/smtp'
|
35
|
-
Net::SMTP.start('your.smtp.server', 25) do |smtp|
|
36
|
-
# Use the SMTP object smtp only in this block.
|
37
|
-
end
|
38
|
-
```
|
39
|
-
|
40
|
-
Replace 'your.smtp.server' with your SMTP server. Normally
|
41
|
-
your system manager or internet provider supplies a server
|
42
|
-
for you.
|
43
|
-
|
44
|
-
Then you can send messages.
|
45
|
-
|
46
|
-
```ruby
|
47
|
-
msgstr = <<END_OF_MESSAGE
|
48
|
-
From: Your Name <your@mail.address>
|
49
|
-
To: Destination Address <someone@example.com>
|
50
|
-
Subject: test message
|
51
|
-
Date: Sat, 23 Jun 2001 16:26:43 +0900
|
52
|
-
Message-Id: <unique.message.id.string@example.com>
|
53
|
-
|
54
|
-
This is a test message.
|
55
|
-
END_OF_MESSAGE
|
56
|
-
|
57
|
-
require 'net/smtp'
|
58
|
-
Net::SMTP.start('your.smtp.server', 25) do |smtp|
|
59
|
-
smtp.send_message msgstr,
|
60
|
-
'your@mail.address',
|
61
|
-
'his_address@example.com'
|
62
|
-
end
|
63
|
-
```
|
64
|
-
|
65
|
-
### Closing the Session
|
66
|
-
|
67
|
-
You MUST close the SMTP session after sending messages, by calling
|
68
|
-
the #finish method:
|
69
|
-
|
70
|
-
```ruby
|
71
|
-
# using SMTP#finish
|
72
|
-
smtp = Net::SMTP.start('your.smtp.server', 25)
|
73
|
-
smtp.send_message msgstr, 'from@address', 'to@address'
|
74
|
-
smtp.finish
|
75
|
-
```
|
76
|
-
|
77
|
-
You can also use the block form of SMTP.start/SMTP#start. This closes
|
78
|
-
the SMTP session automatically:
|
79
|
-
|
80
|
-
```ruby
|
81
|
-
# using block form of SMTP.start
|
82
|
-
Net::SMTP.start('your.smtp.server', 25) do |smtp|
|
83
|
-
smtp.send_message msgstr, 'from@address', 'to@address'
|
84
|
-
end
|
85
|
-
```
|
86
|
-
|
87
|
-
I strongly recommend this scheme. This form is simpler and more robust.
|
88
|
-
|
89
|
-
## Development
|
90
|
-
|
91
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
92
|
-
|
93
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
94
|
-
|
95
|
-
## Contributing
|
96
|
-
|
97
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/net-smtp.
|
data/Rakefile
DELETED
data/bin/console
DELETED