rubysl-net-smtp 1.0.0 → 2.0.1
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/.travis.yml +3 -2
- data/lib/rubysl/net/smtp/smtp.rb +129 -90
- data/lib/rubysl/net/smtp/version.rb +1 -1
- data/rubysl-net-smtp.gemspec +3 -1
- metadata +18 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bbb137dee2422e0cde3cf6afb5406f20b1c9deb1
|
4
|
+
data.tar.gz: 56bddbbda510287ea65d32388d328815b76aa55f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6978d2a1ba12eaca8bdc9e6155d234cc82fd8b53201c5cc40672f115722e129e345a52994dd2bc95594052f21d6c4bee116a764eb9ff61db9bdff7505d69ab1
|
7
|
+
data.tar.gz: 84dce2d4a0d7f978a4538dbd6d41e8cc37523c87416d6e2426870d9fc1c33217f0123d744d3c8824757faf5202a0191773735ce16fd86362d830f0fcdc1cc937
|
data/.travis.yml
CHANGED
data/lib/rubysl/net/smtp/smtp.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
# = net/smtp.rb
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Copyright (c) 1999-2007 Yukihiro Matsumoto.
|
4
4
|
#
|
5
5
|
# Copyright (c) 1999-2007 Minero Aoki.
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# Written & maintained by Minero Aoki <aamine@loveruby.net>.
|
8
8
|
#
|
9
9
|
# Documented by William Webber and Minero Aoki.
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# This program is free software. You can re-distribute and/or
|
12
12
|
# modify this program under the same terms as Ruby itself.
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# NOTE: You can find Japanese version of this document at:
|
15
15
|
# http://www.ruby-lang.org/ja/man/html/net_smtp.html
|
16
|
-
#
|
17
|
-
# $Id$
|
18
16
|
#
|
19
|
-
#
|
20
|
-
#
|
17
|
+
# $Id: smtp.rb 40829 2013-05-19 14:50:47Z kazu $
|
18
|
+
#
|
19
|
+
# See Net::SMTP for documentation.
|
20
|
+
#
|
21
21
|
|
22
22
|
require 'net/protocol'
|
23
23
|
require 'digest/md5'
|
@@ -65,114 +65,112 @@ module Net
|
|
65
65
|
include SMTPError
|
66
66
|
end
|
67
67
|
|
68
|
-
#
|
69
|
-
# = Net::SMTP
|
70
68
|
#
|
71
69
|
# == What is This Library?
|
72
|
-
#
|
70
|
+
#
|
73
71
|
# This library provides functionality to send internet
|
74
72
|
# mail via SMTP, the Simple Mail Transfer Protocol. For details of
|
75
73
|
# SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt).
|
76
|
-
#
|
74
|
+
#
|
77
75
|
# == What is This Library NOT?
|
78
|
-
#
|
76
|
+
#
|
79
77
|
# This library does NOT provide functions to compose internet mails.
|
80
78
|
# You must create them by yourself. If you want better mail support,
|
81
79
|
# try RubyMail or TMail. You can get both libraries from RAA.
|
82
80
|
# (http://www.ruby-lang.org/en/raa.html)
|
83
|
-
#
|
81
|
+
#
|
84
82
|
# FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt).
|
85
|
-
#
|
83
|
+
#
|
86
84
|
# == Examples
|
87
|
-
#
|
85
|
+
#
|
88
86
|
# === Sending Messages
|
89
|
-
#
|
87
|
+
#
|
90
88
|
# You must open a connection to an SMTP server before sending messages.
|
91
|
-
# The first argument is the address of your SMTP server, and the second
|
92
|
-
# argument is the port number. Using SMTP.start with a block is the simplest
|
93
|
-
# way to do this. This way, the SMTP connection is closed automatically
|
89
|
+
# The first argument is the address of your SMTP server, and the second
|
90
|
+
# argument is the port number. Using SMTP.start with a block is the simplest
|
91
|
+
# way to do this. This way, the SMTP connection is closed automatically
|
94
92
|
# after the block is executed.
|
95
|
-
#
|
93
|
+
#
|
96
94
|
# require 'net/smtp'
|
97
95
|
# Net::SMTP.start('your.smtp.server', 25) do |smtp|
|
98
96
|
# # Use the SMTP object smtp only in this block.
|
99
97
|
# end
|
100
|
-
#
|
98
|
+
#
|
101
99
|
# Replace 'your.smtp.server' with your SMTP server. Normally
|
102
100
|
# your system manager or internet provider supplies a server
|
103
101
|
# for you.
|
104
|
-
#
|
102
|
+
#
|
105
103
|
# Then you can send messages.
|
106
|
-
#
|
104
|
+
#
|
107
105
|
# msgstr = <<END_OF_MESSAGE
|
108
106
|
# From: Your Name <your@mail.address>
|
109
107
|
# To: Destination Address <someone@example.com>
|
110
108
|
# Subject: test message
|
111
109
|
# Date: Sat, 23 Jun 2001 16:26:43 +0900
|
112
110
|
# Message-Id: <unique.message.id.string@example.com>
|
113
|
-
#
|
111
|
+
#
|
114
112
|
# This is a test message.
|
115
113
|
# END_OF_MESSAGE
|
116
|
-
#
|
114
|
+
#
|
117
115
|
# require 'net/smtp'
|
118
116
|
# Net::SMTP.start('your.smtp.server', 25) do |smtp|
|
119
117
|
# smtp.send_message msgstr,
|
120
118
|
# 'your@mail.address',
|
121
|
-
# '
|
119
|
+
# 'his_address@example.com'
|
122
120
|
# end
|
123
|
-
#
|
121
|
+
#
|
124
122
|
# === Closing the Session
|
125
|
-
#
|
126
|
-
# You MUST close the SMTP session after sending messages, by calling
|
123
|
+
#
|
124
|
+
# You MUST close the SMTP session after sending messages, by calling
|
127
125
|
# the #finish method:
|
128
|
-
#
|
126
|
+
#
|
129
127
|
# # using SMTP#finish
|
130
128
|
# smtp = Net::SMTP.start('your.smtp.server', 25)
|
131
129
|
# smtp.send_message msgstr, 'from@address', 'to@address'
|
132
130
|
# smtp.finish
|
133
|
-
#
|
131
|
+
#
|
134
132
|
# You can also use the block form of SMTP.start/SMTP#start. This closes
|
135
133
|
# the SMTP session automatically:
|
136
|
-
#
|
134
|
+
#
|
137
135
|
# # using block form of SMTP.start
|
138
136
|
# Net::SMTP.start('your.smtp.server', 25) do |smtp|
|
139
137
|
# smtp.send_message msgstr, 'from@address', 'to@address'
|
140
138
|
# end
|
141
|
-
#
|
139
|
+
#
|
142
140
|
# I strongly recommend this scheme. This form is simpler and more robust.
|
143
|
-
#
|
141
|
+
#
|
144
142
|
# === HELO domain
|
145
|
-
#
|
143
|
+
#
|
146
144
|
# In almost all situations, you must provide a third argument
|
147
145
|
# to SMTP.start/SMTP#start. This is the domain name which you are on
|
148
146
|
# (the host to send mail from). It is called the "HELO domain".
|
149
147
|
# The SMTP server will judge whether it should send or reject
|
150
148
|
# the SMTP session by inspecting the HELO domain.
|
151
|
-
#
|
149
|
+
#
|
152
150
|
# Net::SMTP.start('your.smtp.server', 25,
|
153
151
|
# 'mail.from.domain') { |smtp| ... }
|
154
|
-
#
|
152
|
+
#
|
155
153
|
# === SMTP Authentication
|
156
|
-
#
|
154
|
+
#
|
157
155
|
# The Net::SMTP class supports three authentication schemes;
|
158
156
|
# PLAIN, LOGIN and CRAM MD5. (SMTP Authentication: [RFC2554])
|
159
|
-
# To use SMTP authentication, pass extra arguments to
|
157
|
+
# To use SMTP authentication, pass extra arguments to
|
160
158
|
# SMTP.start/SMTP#start.
|
161
|
-
#
|
159
|
+
#
|
162
160
|
# # PLAIN
|
163
161
|
# Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
|
164
162
|
# 'Your Account', 'Your Password', :plain)
|
165
163
|
# # LOGIN
|
166
164
|
# Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
|
167
165
|
# 'Your Account', 'Your Password', :login)
|
168
|
-
#
|
166
|
+
#
|
169
167
|
# # CRAM MD5
|
170
168
|
# Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
|
171
169
|
# 'Your Account', 'Your Password', :cram_md5)
|
172
170
|
#
|
173
171
|
class SMTP
|
174
172
|
|
175
|
-
Revision = %q$Revision$.split[1]
|
173
|
+
Revision = %q$Revision: 40829 $.split[1]
|
176
174
|
|
177
175
|
# The default SMTP port number, 25.
|
178
176
|
def SMTP.default_port
|
@@ -196,7 +194,7 @@ module Net
|
|
196
194
|
def SMTP.default_ssl_context
|
197
195
|
OpenSSL::SSL::SSLContext.new
|
198
196
|
end
|
199
|
-
|
197
|
+
|
200
198
|
#
|
201
199
|
# Creates a new Net::SMTP object.
|
202
200
|
#
|
@@ -217,35 +215,29 @@ module Net
|
|
217
215
|
@started = false
|
218
216
|
@open_timeout = 30
|
219
217
|
@read_timeout = 60
|
220
|
-
@
|
218
|
+
@error_occurred = false
|
221
219
|
@debug_output = nil
|
222
220
|
@tls = false
|
223
221
|
@starttls = false
|
224
222
|
@ssl_context = nil
|
225
223
|
end
|
226
|
-
|
224
|
+
|
227
225
|
# Provide human-readable stringification of class state.
|
228
226
|
def inspect
|
229
227
|
"#<#{self.class} #{@address}:#{@port} started=#{@started}>"
|
230
228
|
end
|
231
229
|
|
232
|
-
# +true+ if the SMTP object uses ESMTP (which it does by default).
|
233
|
-
def esmtp?
|
234
|
-
@esmtp
|
235
|
-
end
|
236
|
-
|
237
230
|
#
|
238
|
-
# Set whether to use ESMTP or not. This should be done before
|
231
|
+
# Set whether to use ESMTP or not. This should be done before
|
239
232
|
# calling #start. Note that if #start is called in ESMTP mode,
|
240
233
|
# and the connection fails due to a ProtocolError, the SMTP
|
241
234
|
# object will automatically switch to plain SMTP mode and
|
242
235
|
# retry (but not vice versa).
|
243
236
|
#
|
244
|
-
|
245
|
-
@esmtp = bool
|
246
|
-
end
|
237
|
+
attr_accessor :esmtp
|
247
238
|
|
248
|
-
|
239
|
+
# +true+ if the SMTP object uses ESMTP (which it does by default).
|
240
|
+
alias :esmtp? :esmtp
|
249
241
|
|
250
242
|
# true if server advertises STARTTLS.
|
251
243
|
# You cannot get valid value before opening SMTP session.
|
@@ -310,7 +302,7 @@ module Net
|
|
310
302
|
end
|
311
303
|
|
312
304
|
alias enable_ssl enable_tls
|
313
|
-
|
305
|
+
|
314
306
|
# Disables SMTP/TLS for this object. Must be called before the
|
315
307
|
# connection is established to have any effect.
|
316
308
|
def disable_tls
|
@@ -336,7 +328,7 @@ module Net
|
|
336
328
|
def starttls_auto?
|
337
329
|
@starttls == :auto
|
338
330
|
end
|
339
|
-
|
331
|
+
|
340
332
|
# Enables SMTP/TLS (STARTTLS) for this object.
|
341
333
|
# +context+ is a OpenSSL::SSL::SSLContext object.
|
342
334
|
def enable_starttls(context = SMTP.default_ssl_context)
|
@@ -370,12 +362,12 @@ module Net
|
|
370
362
|
|
371
363
|
# Seconds to wait while attempting to open a connection.
|
372
364
|
# If the connection cannot be opened within this time, a
|
373
|
-
#
|
365
|
+
# Net::OpenTimeout is raised. The default value is 30 seconds.
|
374
366
|
attr_accessor :open_timeout
|
375
367
|
|
376
368
|
# Seconds to wait while reading one block (by one read(2) call).
|
377
369
|
# If the read(2) call does not complete within this time, a
|
378
|
-
#
|
370
|
+
# Net::ReadTimeout is raised. The default value is 60 seconds.
|
379
371
|
attr_reader :read_timeout
|
380
372
|
|
381
373
|
# Set the number of seconds to wait until timing-out a read(2)
|
@@ -413,7 +405,7 @@ module Net
|
|
413
405
|
# Creates a new Net::SMTP object and connects to the server.
|
414
406
|
#
|
415
407
|
# This method is equivalent to:
|
416
|
-
#
|
408
|
+
#
|
417
409
|
# Net::SMTP.new(address, port).start(helo_domain, account, password, authtype)
|
418
410
|
#
|
419
411
|
# === Example
|
@@ -437,7 +429,7 @@ module Net
|
|
437
429
|
# +port+ is the port to connect to; it defaults to port 25.
|
438
430
|
#
|
439
431
|
# +helo+ is the _HELO_ _domain_ provided by the client to the
|
440
|
-
# server (see overview comments); it defaults to 'localhost
|
432
|
+
# server (see overview comments); it defaults to 'localhost'.
|
441
433
|
#
|
442
434
|
# The remaining arguments are used for SMTP authentication, if required
|
443
435
|
# or desired. +user+ is the account name; +secret+ is your password
|
@@ -454,10 +446,11 @@ module Net
|
|
454
446
|
# * Net::SMTPSyntaxError
|
455
447
|
# * Net::SMTPFatalError
|
456
448
|
# * Net::SMTPUnknownError
|
449
|
+
# * Net::OpenTimeout
|
450
|
+
# * Net::ReadTimeout
|
457
451
|
# * IOError
|
458
|
-
# * TimeoutError
|
459
452
|
#
|
460
|
-
def SMTP.start(address, port = nil, helo = 'localhost
|
453
|
+
def SMTP.start(address, port = nil, helo = 'localhost',
|
461
454
|
user = nil, secret = nil, authtype = nil,
|
462
455
|
&block) # :yield: smtp
|
463
456
|
new(address, port).start(helo, user, secret, authtype, &block)
|
@@ -476,33 +469,33 @@ module Net
|
|
476
469
|
# +helo+ is the _HELO_ _domain_ that you'll dispatch mails from; see
|
477
470
|
# the discussion in the overview notes.
|
478
471
|
#
|
479
|
-
# If both of +user+ and +secret+ are given, SMTP authentication
|
480
|
-
# will be attempted using the AUTH command. +authtype+ specifies
|
472
|
+
# If both of +user+ and +secret+ are given, SMTP authentication
|
473
|
+
# will be attempted using the AUTH command. +authtype+ specifies
|
481
474
|
# the type of authentication to attempt; it must be one of
|
482
475
|
# :login, :plain, and :cram_md5. See the notes on SMTP Authentication
|
483
|
-
# in the overview.
|
476
|
+
# in the overview.
|
484
477
|
#
|
485
478
|
# === Block Usage
|
486
479
|
#
|
487
480
|
# When this methods is called with a block, the newly-started SMTP
|
488
481
|
# object is yielded to the block, and automatically closed after
|
489
|
-
# the block call finishes. Otherwise, it is the caller's
|
482
|
+
# the block call finishes. Otherwise, it is the caller's
|
490
483
|
# responsibility to close the session when finished.
|
491
484
|
#
|
492
485
|
# === Example
|
493
486
|
#
|
494
487
|
# This is very similar to the class method SMTP.start.
|
495
488
|
#
|
496
|
-
# require 'net/smtp'
|
489
|
+
# require 'net/smtp'
|
497
490
|
# smtp = Net::SMTP.new('smtp.mail.server', 25)
|
498
491
|
# smtp.start(helo_domain, account, password, authtype) do |smtp|
|
499
492
|
# smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
|
500
|
-
# end
|
493
|
+
# end
|
501
494
|
#
|
502
495
|
# The primary use of this method (as opposed to SMTP.start)
|
503
496
|
# is probably to set debugging (#set_debug_output) or ESMTP
|
504
497
|
# (#esmtp=), which must be done before the session is
|
505
|
-
# started.
|
498
|
+
# started.
|
506
499
|
#
|
507
500
|
# === Errors
|
508
501
|
#
|
@@ -515,10 +508,11 @@ module Net
|
|
515
508
|
# * Net::SMTPSyntaxError
|
516
509
|
# * Net::SMTPFatalError
|
517
510
|
# * Net::SMTPUnknownError
|
511
|
+
# * Net::OpenTimeout
|
512
|
+
# * Net::ReadTimeout
|
518
513
|
# * IOError
|
519
|
-
# * TimeoutError
|
520
514
|
#
|
521
|
-
def start(helo = 'localhost
|
515
|
+
def start(helo = 'localhost',
|
522
516
|
user = nil, secret = nil, authtype = nil) # :yield: smtp
|
523
517
|
if block_given?
|
524
518
|
begin
|
@@ -542,13 +536,19 @@ module Net
|
|
542
536
|
|
543
537
|
private
|
544
538
|
|
539
|
+
def tcp_socket(address, port)
|
540
|
+
TCPSocket.open address, port
|
541
|
+
end
|
542
|
+
|
545
543
|
def do_start(helo_domain, user, secret, authtype)
|
546
544
|
raise IOError, 'SMTP session already started' if @started
|
547
545
|
if user or secret
|
548
546
|
check_auth_method(authtype || DEFAULT_AUTH_TYPE)
|
549
547
|
check_auth_args user, secret
|
550
548
|
end
|
551
|
-
s = timeout(@open_timeout
|
549
|
+
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do
|
550
|
+
tcp_socket(@address, @port)
|
551
|
+
end
|
552
552
|
logging "Connection opened: #{@address}:#{@port}"
|
553
553
|
@socket = new_internet_message_io(tls? ? tlsconnect(s) : s)
|
554
554
|
check_response critical { recv_response() }
|
@@ -573,15 +573,23 @@ module Net
|
|
573
573
|
end
|
574
574
|
end
|
575
575
|
|
576
|
+
def ssl_socket(socket, context)
|
577
|
+
OpenSSL::SSL::SSLSocket.new socket, context
|
578
|
+
end
|
579
|
+
|
576
580
|
def tlsconnect(s)
|
577
|
-
|
581
|
+
verified = false
|
582
|
+
s = ssl_socket(s, @ssl_context)
|
578
583
|
logging "TLS connection started"
|
579
584
|
s.sync_close = true
|
580
585
|
s.connect
|
581
586
|
if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
|
582
587
|
s.post_connection_check(@address)
|
583
588
|
end
|
589
|
+
verified = true
|
584
590
|
s
|
591
|
+
ensure
|
592
|
+
s.close unless verified
|
585
593
|
end
|
586
594
|
|
587
595
|
def new_internet_message_io(s)
|
@@ -597,17 +605,17 @@ module Net
|
|
597
605
|
rescue SMTPError
|
598
606
|
if @esmtp
|
599
607
|
@esmtp = false
|
600
|
-
@
|
608
|
+
@error_occurred = false
|
601
609
|
retry
|
602
610
|
end
|
603
611
|
raise
|
604
612
|
end
|
605
613
|
|
606
614
|
def do_finish
|
607
|
-
quit if @socket and not @socket.closed? and not @
|
615
|
+
quit if @socket and not @socket.closed? and not @error_occurred
|
608
616
|
ensure
|
609
617
|
@started = false
|
610
|
-
@
|
618
|
+
@error_occurred = false
|
611
619
|
@socket.close if @socket and not @socket.closed?
|
612
620
|
@socket = nil
|
613
621
|
end
|
@@ -621,7 +629,7 @@ module Net
|
|
621
629
|
#
|
622
630
|
# Sends +msgstr+ as a message. Single CR ("\r") and LF ("\n") found
|
623
631
|
# in the +msgstr+, are converted into the CR LF pair. You cannot send a
|
624
|
-
# binary message with this method. +msgstr+ should include both
|
632
|
+
# binary message with this method. +msgstr+ should include both
|
625
633
|
# the message headers and body.
|
626
634
|
#
|
627
635
|
# +from_addr+ is a String representing the source mail address.
|
@@ -645,8 +653,8 @@ module Net
|
|
645
653
|
# * Net::SMTPSyntaxError
|
646
654
|
# * Net::SMTPFatalError
|
647
655
|
# * Net::SMTPUnknownError
|
656
|
+
# * Net::ReadTimeout
|
648
657
|
# * IOError
|
649
|
-
# * TimeoutError
|
650
658
|
#
|
651
659
|
def send_message(msgstr, from_addr, *to_addrs)
|
652
660
|
raise IOError, 'closed session' unless @socket
|
@@ -698,8 +706,8 @@ module Net
|
|
698
706
|
# * Net::SMTPSyntaxError
|
699
707
|
# * Net::SMTPFatalError
|
700
708
|
# * Net::SMTPUnknownError
|
709
|
+
# * Net::ReadTimeout
|
701
710
|
# * IOError
|
702
|
-
# * TimeoutError
|
703
711
|
#
|
704
712
|
def open_message_stream(from_addr, *to_addrs, &block) # :yield: stream
|
705
713
|
raise IOError, 'closed session' unless @socket
|
@@ -767,7 +775,7 @@ module Net
|
|
767
775
|
"auth_#{type.to_s.downcase}".intern
|
768
776
|
end
|
769
777
|
|
770
|
-
def check_auth_args(user, secret)
|
778
|
+
def check_auth_args(user, secret, authtype = DEFAULT_AUTH_TYPE)
|
771
779
|
unless user
|
772
780
|
raise ArgumentError, 'SMTP-AUTH requested but missing user name'
|
773
781
|
end
|
@@ -807,6 +815,12 @@ module Net
|
|
807
815
|
|
808
816
|
public
|
809
817
|
|
818
|
+
# Aborts the current mail transaction
|
819
|
+
|
820
|
+
def rset
|
821
|
+
getok('RSET')
|
822
|
+
end
|
823
|
+
|
810
824
|
def starttls
|
811
825
|
getok('STARTTLS')
|
812
826
|
end
|
@@ -864,7 +878,7 @@ module Net
|
|
864
878
|
# From: john@example.com
|
865
879
|
# To: betty@example.com
|
866
880
|
# Subject: I found a bug
|
867
|
-
#
|
881
|
+
#
|
868
882
|
# Check vm.c:58879.
|
869
883
|
# EndMessage
|
870
884
|
#
|
@@ -927,12 +941,12 @@ module Net
|
|
927
941
|
Response.parse(buf)
|
928
942
|
end
|
929
943
|
|
930
|
-
def critical
|
931
|
-
return '200 dummy reply code' if @
|
944
|
+
def critical
|
945
|
+
return '200 dummy reply code' if @error_occurred
|
932
946
|
begin
|
933
947
|
return yield()
|
934
948
|
rescue Exception
|
935
|
-
@
|
949
|
+
@error_occurred = true
|
936
950
|
raise
|
937
951
|
end
|
938
952
|
end
|
@@ -945,7 +959,7 @@ module Net
|
|
945
959
|
|
946
960
|
def check_continue(res)
|
947
961
|
unless res.continue?
|
948
|
-
raise SMTPUnknownError, "could not get 3xx (#{res.status})"
|
962
|
+
raise SMTPUnknownError, "could not get 3xx (#{res.status}: #{res.string})"
|
949
963
|
end
|
950
964
|
end
|
951
965
|
|
@@ -961,49 +975,74 @@ module Net
|
|
961
975
|
end
|
962
976
|
end
|
963
977
|
|
978
|
+
# This class represents a response received by the SMTP server. Instances
|
979
|
+
# of this class are created by the SMTP class; they should not be directly
|
980
|
+
# created by the user. For more information on SMTP responses, view
|
981
|
+
# {Section 4.2 of RFC 5321}[http://tools.ietf.org/html/rfc5321#section-4.2]
|
964
982
|
class Response
|
965
|
-
|
983
|
+
# Parses the received response and separates the reply code and the human
|
984
|
+
# readable reply text
|
985
|
+
def self.parse(str)
|
966
986
|
new(str[0,3], str)
|
967
987
|
end
|
968
988
|
|
989
|
+
# Creates a new instance of the Response class and sets the status and
|
990
|
+
# string attributes
|
969
991
|
def initialize(status, string)
|
970
992
|
@status = status
|
971
993
|
@string = string
|
972
994
|
end
|
973
995
|
|
996
|
+
# The three digit reply code of the SMTP response
|
974
997
|
attr_reader :status
|
998
|
+
|
999
|
+
# The human readable reply text of the SMTP response
|
975
1000
|
attr_reader :string
|
976
1001
|
|
1002
|
+
# Takes the first digit of the reply code to determine the status type
|
977
1003
|
def status_type_char
|
978
1004
|
@status[0, 1]
|
979
1005
|
end
|
980
1006
|
|
1007
|
+
# Determines whether the response received was a Positive Completion
|
1008
|
+
# reply (2xx reply code)
|
981
1009
|
def success?
|
982
1010
|
status_type_char() == '2'
|
983
1011
|
end
|
984
1012
|
|
1013
|
+
# Determines whether the response received was a Positive Intermediate
|
1014
|
+
# reply (3xx reply code)
|
985
1015
|
def continue?
|
986
1016
|
status_type_char() == '3'
|
987
1017
|
end
|
988
1018
|
|
1019
|
+
# The first line of the human readable reply text
|
989
1020
|
def message
|
990
1021
|
@string.lines.first
|
991
1022
|
end
|
992
1023
|
|
1024
|
+
# Creates a CRAM-MD5 challenge. You can view more information on CRAM-MD5
|
1025
|
+
# on Wikipedia: http://en.wikipedia.org/wiki/CRAM-MD5
|
993
1026
|
def cram_md5_challenge
|
994
1027
|
@string.split(/ /)[1].unpack('m')[0]
|
995
1028
|
end
|
996
1029
|
|
1030
|
+
# Returns a hash of the human readable reply text in the response if it
|
1031
|
+
# is multiple lines. It does not return the first line. The key of the
|
1032
|
+
# hash is the first word the value of the hash is an array with each word
|
1033
|
+
# thereafter being a value in the array
|
997
1034
|
def capabilities
|
998
1035
|
return {} unless @string[3, 1] == '-'
|
999
1036
|
h = {}
|
1000
1037
|
@string.lines.drop(1).each do |line|
|
1001
|
-
k, *v = line[4..-1].chomp.split
|
1038
|
+
k, *v = line[4..-1].chomp.split
|
1002
1039
|
h[k] = v
|
1003
1040
|
end
|
1004
1041
|
h
|
1005
1042
|
end
|
1006
1043
|
|
1044
|
+
# Determines whether there was an error and raies the appropriate error
|
1045
|
+
# based on the reply code of the response
|
1007
1046
|
def exception_class
|
1008
1047
|
case @status
|
1009
1048
|
when /\A4/ then SMTPServerBusy
|
@@ -1021,6 +1060,6 @@ module Net
|
|
1021
1060
|
|
1022
1061
|
end # class SMTP
|
1023
1062
|
|
1024
|
-
SMTPSession = SMTP
|
1063
|
+
SMTPSession = SMTP # :nodoc:
|
1025
1064
|
|
1026
1065
|
end
|
data/rubysl-net-smtp.gemspec
CHANGED
@@ -16,8 +16,10 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
17
|
spec.require_paths = ["lib"]
|
18
18
|
|
19
|
+
spec.required_ruby_version = "~> 2.0"
|
20
|
+
|
19
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
20
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
21
23
|
spec.add_development_dependency "mspec", "~> 1.5"
|
22
|
-
spec.add_development_dependency "rubysl-prettyprint", "~>
|
24
|
+
spec.add_development_dependency "rubysl-prettyprint", "~> 2.0"
|
23
25
|
end
|
metadata
CHANGED
@@ -1,71 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubysl-net-smtp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Shirai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: mspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.5'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.5'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rubysl-prettyprint
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '2.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '2.0'
|
69
69
|
description: Ruby standard library smtp.
|
70
70
|
email:
|
71
71
|
- brixen@gmail.com
|
@@ -73,8 +73,8 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
-
- .gitignore
|
77
|
-
- .travis.yml
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
78
|
- Gemfile
|
79
79
|
- LICENSE
|
80
80
|
- README.md
|
@@ -94,12 +94,12 @@ require_paths:
|
|
94
94
|
- lib
|
95
95
|
required_ruby_version: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
|
-
- -
|
97
|
+
- - "~>"
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version: '0'
|
99
|
+
version: '2.0'
|
100
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- -
|
102
|
+
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '0'
|
105
105
|
requirements: []
|
@@ -109,3 +109,4 @@ signing_key:
|
|
109
109
|
specification_version: 4
|
110
110
|
summary: Ruby standard library smtp.
|
111
111
|
test_files: []
|
112
|
+
has_rdoc:
|