rubysl-net-smtp 1.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|