1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/net/smtp.rb: changes coding style.

* lib/net/pop.rb: ditto.
* lib/net/protocol.rb: ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3071 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
aamine 2002-11-21 11:50:09 +00:00
parent 15911a95bf
commit f80af5150a
4 changed files with 131 additions and 118 deletions

View file

@ -1,6 +1,14 @@
Thu Nov 21 20:53:06 2002 Minero Aoki <aamine@loveruby.net>
* lib/net/smtp.rb: changes coding style.
* lib/net/pop.rb: ditto.
* lib/net/protocol.rb: ditto.
Thu Nov 21 20:17:08 2002 Minero Aoki <aamine@loveruby.net> Thu Nov 21 20:17:08 2002 Minero Aoki <aamine@loveruby.net>
* lib/net/http.rb: unify coding style. * lib/net/http.rb: changes coding style.
Thu Nov 21 20:04:06 2002 Minero Aoki <aamine@loveruby.net> Thu Nov 21 20:04:06 2002 Minero Aoki <aamine@loveruby.net>

View file

@ -341,33 +341,33 @@ module Net
protocol_param :socket_type, '::Net::InternetMessageIO' protocol_param :socket_type, '::Net::InternetMessageIO'
def POP3.APOP( bool ) def POP3.APOP( isapop )
bool ? APOP : POP3 isapop ? APOP : POP3
end end
def POP3.foreach( address, port = nil, def POP3.foreach( address, port = nil,
account = nil, password = nil, &block ) account = nil, password = nil, &block )
start( address, port, account, password ) {|pop| start(address, port, account, password) {|pop|
pop.each_mail( &block ) pop.each_mail(&block)
} }
end end
def POP3.delete_all( address, port = nil, def POP3.delete_all( address, port = nil,
account = nil, password = nil, &block ) account = nil, password = nil, &block )
start( address, port, account, password ) {|pop| start(address, port, account, password) {|pop|
pop.delete_all( &block ) pop.delete_all(&block)
} }
end end
def POP3.auth_only( address, port = nil, def POP3.auth_only( address, port = nil,
account = nil, password = nil ) account = nil, password = nil )
new( address, port ).auth_only account, password new(address, port).auth_only account, password
end end
def auth_only( account, password ) def auth_only( account, password )
raise IOError, 'opening already opened POP session' if active? raise IOError, 'opening already opened POP session' if active?
start( account, password ) { start(account, password) {
# none # none
} }
end end
@ -387,10 +387,15 @@ module Net
def do_start( account, password ) def do_start( account, password )
conn_socket conn_socket
@command = (@apop ? self.class.apop_command_type : self.class.command_type).new(socket()) conn_command
@command.auth account, password @command.auth account, password
end end
def conn_command
@command = (@apop ? self.class.apop_command_type :
self.class.command_type).new(socket())
end
def do_finish def do_finish
@mails = nil @mails = nil
disconn_command disconn_command
@ -408,15 +413,15 @@ module Net
return @mails if @mails return @mails if @mails
mails = [] mails = []
mtype = self.class.mail_type mailclass = self.class.mail_type
command().list.each_with_index do |size,idx| command().list.each_with_index do |size,idx|
mails.push mtype.new(idx, size, command()) if size mails.push mailclass.new(idx, size, command()) if size
end end
@mails = mails.freeze @mails = mails.freeze
end end
def each_mail( &block ) def each_mail( &block )
mails().each( &block ) mails().each(&block)
end end
alias each each_mail alias each each_mail
@ -479,7 +484,7 @@ module Net
end end
def pop( dest = '', &block ) def pop( dest = '', &block )
if block then if block
dest = ReadAdapter.new(block) dest = ReadAdapter.new(block)
end end
@command.retr @num, dest @command.retr @num, dest
@ -540,7 +545,7 @@ module Net
@socket.each_list_item do |line| @socket.each_list_item do |line|
m = /\A(\d+)[ \t]+(\d+)/.match(line) or m = /\A(\d+)[ \t]+(\d+)/.match(line) or
raise BadResponse, "illegal response: #{line}" raise BadResponse, "illegal response: #{line}"
arr[ m[1].to_i ] = m[2].to_i arr[m[1].to_i] = m[2].to_i
end end
} }
arr arr
@ -575,7 +580,7 @@ module Net
def uidl( num ) def uidl( num )
atomic { atomic {
getok( sprintf('UIDL %d', num) ).message.split(' ')[1] getok(sprintf('UIDL %d', num)).message.split(/ /)[1]
} }
end end
@ -598,10 +603,10 @@ module Net
def get_reply def get_reply
str = @socket.readline str = @socket.readline
if /\A\+/ === str then if /\A\+/ === str
Response.new( SuccessCode, str[0,3], str[3, str.size - 3].strip ) Response.new(SuccessCode, str[0,3], str[3, str.size - 3].strip)
else else
Response.new( ErrorCode, str[0,4], str[4, str.size - 4].strip ) Response.new(ErrorCode, str[0,4], str[4, str.size - 4].strip)
end end
end end

View file

@ -25,8 +25,8 @@ module Net
class Protocol class Protocol
Version = '1.2.3' Version = '1.2.3'
Revision = %q$Revision$.split(/\s+/)[1] Revision = '$Revision$'.slice(/[\d\.]+/)
class << self class << self
@ -38,11 +38,11 @@ module Net
private private
def protocol_param( name, val ) def protocol_param( name, val )
module_eval <<-End, __FILE__, __LINE__ + 1 module_eval <<-EOS, __FILE__, __LINE__ + 1
def self.#{name.id2name} def self.#{name.id2name}
#{val} #{val}
end end
End EOS
end end
end end
@ -65,9 +65,10 @@ module Net
def Protocol.start( address, port = nil, *args ) def Protocol.start( address, port = nil, *args )
instance = new(address, port) instance = new(address, port)
if block_given?
if block_given? then instance.start(*args) {
instance.start(*args) { return yield(instance) } return yield(instance)
}
else else
instance.start(*args) instance.start(*args)
instance instance
@ -125,9 +126,9 @@ module Net
def start( *args ) def start( *args )
@started and raise IOError, 'protocol has been opened already' @started and raise IOError, 'protocol has been opened already'
if block_given? then if block_given?
begin begin
do_start( *args ) do_start(*args)
@started = true @started = true
return yield(self) return yield(self)
ensure ensure
@ -135,7 +136,7 @@ module Net
end end
end end
do_start( *args ) do_start(*args)
@started = true @started = true
self self
end end
@ -173,7 +174,7 @@ module Net
public public
def finish def finish
@started or raise IOError, 'closing already closed protocol' raise IOError, 'closing already closed protocol' unless @started
do_finish do_finish
@started = false @started = false
nil nil
@ -189,9 +190,7 @@ module Net
end end
def disconn_socket def disconn_socket
if @socket and not @socket.closed? then @socket.close if @socket and not @socket.closed?
@socket.close
end
@socket = nil @socket = nil
end end
@ -274,7 +273,9 @@ module Net
end end
def ===( response ) def ===( response )
response.code_type.parents.each {|c| c == self and return true } response.code_type.parents.each do |c|
return true if c == self
end
false false
end end
@ -284,17 +285,17 @@ module Net
end end
ReplyCode = Code.new( [], ProtoUnknownError ) ReplyCode = Code.new([], ProtoUnknownError)
InformationCode = ReplyCode.mkchild( ProtoUnknownError ) InformationCode = ReplyCode.mkchild(ProtoUnknownError)
SuccessCode = ReplyCode.mkchild( ProtoUnknownError ) SuccessCode = ReplyCode.mkchild(ProtoUnknownError)
ContinueCode = ReplyCode.mkchild( ProtoUnknownError ) ContinueCode = ReplyCode.mkchild(ProtoUnknownError)
ErrorCode = ReplyCode.mkchild( ProtocolError ) ErrorCode = ReplyCode.mkchild(ProtocolError)
SyntaxErrorCode = ErrorCode.mkchild( ProtoSyntaxError ) SyntaxErrorCode = ErrorCode.mkchild(ProtoSyntaxError)
FatalErrorCode = ErrorCode.mkchild( ProtoFatalError ) FatalErrorCode = ErrorCode.mkchild(ProtoFatalError)
ServerErrorCode = ErrorCode.mkchild( ProtoServerError ) ServerErrorCode = ErrorCode.mkchild(ProtoServerError)
AuthErrorCode = ErrorCode.mkchild( ProtoAuthError ) AuthErrorCode = ErrorCode.mkchild(ProtoAuthError)
RetriableCode = ReplyCode.mkchild( ProtoRetriableError ) RetriableCode = ReplyCode.mkchild(ProtoRetriableError)
UnknownCode = ReplyCode.mkchild( ProtoUnknownError ) UnknownCode = ReplyCode.mkchild(ProtoUnknownError)
class Command class Command
@ -394,15 +395,15 @@ module Net
def connect( otime ) def connect( otime )
D "opening connection to #{@address}..." D "opening connection to #{@address}..."
timeout( otime ) { timeout(otime) {
@socket = TCPSocket.new( @address, @port ) @socket = TCPsocket.new(@address, @port)
} }
@rbuf = '' @rbuf = ''
end end
private :connect private :connect
def close def close
if @socket then if @socket
@socket.close @socket.close
D 'closed' D 'closed'
else else
@ -438,7 +439,7 @@ module Net
rsize = 0 rsize = 0
begin begin
while rsize + @rbuf.size < len do while rsize + @rbuf.size < len
rsize += rbuf_moveto(dest, @rbuf.size) rsize += rbuf_moveto(dest, @rbuf.size)
rbuf_fill rbuf_fill
end end
@ -456,7 +457,7 @@ module Net
rsize = 0 rsize = 0
begin begin
while true do while true
rsize += rbuf_moveto(dest, @rbuf.size) rsize += rbuf_moveto(dest, @rbuf.size)
rbuf_fill rbuf_fill
end end
@ -471,9 +472,7 @@ module Net
def readuntil( target, ignore = false ) def readuntil( target, ignore = false )
dest = '' dest = ''
begin begin
while true do until idx = @rbuf.index(target)
idx = @rbuf.index(target)
break if idx
rbuf_fill rbuf_fill
end end
rbuf_moveto dest, idx + target.size rbuf_moveto dest, idx + target.size
@ -495,7 +494,7 @@ module Net
BLOCK_SIZE = 1024 BLOCK_SIZE = 1024
def rbuf_fill def rbuf_fill
until IO.select [@socket], nil, nil, @read_timeout do until IO.select [@socket], nil, nil, @read_timeout
on_read_timeout on_read_timeout
end end
@rbuf << @socket.sysread(BLOCK_SIZE) @rbuf << @socket.sysread(BLOCK_SIZE)
@ -521,7 +520,7 @@ module Net
D_off 'reading text...' D_off 'reading text...'
rsize = 0 rsize = 0
while (str = readuntil("\r\n")) != ".\r\n" do while (str = readuntil("\r\n")) != ".\r\n"
rsize += str.size rsize += str.size
dest << str.sub(/\A\./, '') dest << str.sub(/\A\./, '')
end end
@ -532,7 +531,7 @@ module Net
# private use only (cannot handle 'break') # private use only (cannot handle 'break')
def each_list_item def each_list_item
while (str = readuntil("\r\n")) != ".\r\n" do while (str = readuntil("\r\n")) != ".\r\n"
yield str.chop yield str.chop
end end
end end
@ -610,7 +609,7 @@ module Net
def wpend_in( src ) def wpend_in( src )
line = nil line = nil
pre = @writtensize pre = @writtensize
each_crlf_line( src ) do |line| each_crlf_line(src) do |line|
do_write '.' if line[0] == ?. do_write '.' if line[0] == ?.
do_write line do_write line
end end
@ -624,13 +623,13 @@ module Net
yield yield
if not @wbuf.empty? then # unterminated last line if not @wbuf.empty? # unterminated last line
if @wbuf[-1] == ?\r then if @wbuf[-1] == ?\r
@wbuf.chop! @wbuf.chop!
end end
@wbuf.concat "\r\n" @wbuf.concat "\r\n"
do_write @wbuf do_write @wbuf
elsif @writtensize == 0 then # empty src elsif @writtensize == 0 # empty src
do_write "\r\n" do_write "\r\n"
end end
do_write ".\r\n" do_write ".\r\n"
@ -642,12 +641,12 @@ module Net
def each_crlf_line( src ) def each_crlf_line( src )
str = m = beg = nil str = m = beg = nil
adding( src ) do adding(src) do
beg = 0 beg = 0
buf = @wbuf buf = @wbuf
while buf.index( /\n|\r\n|\r/, beg ) do while buf.index(/\n|\r\n|\r/, beg)
m = Regexp.last_match m = Regexp.last_match
if m.begin(0) == buf.size - 1 and buf[-1] == ?\r then if m.begin(0) == buf.size - 1 and buf[-1] == ?\r
# "...\r" : can follow "\n..." # "...\r" : can follow "\n..."
break break
end end
@ -661,30 +660,26 @@ module Net
end end
def adding( src ) def adding( src )
i = nil i = s = nil
case src case src
when String when String
0.step( src.size - 1, 2048 ) do |i| 0.step(src.size - 1, 2048) do |i|
@wbuf << src[i,2048] @wbuf << src[i,2048]
yield yield
end end
when File when File
while true do while s = src.read(2048)
i = src.read(2048) s[0,0] = @wbuf
break unless i @wbuf = s
i[0,0] = @wbuf
@wbuf = i
yield yield
end end
else else
src.each do |i| src.each do |s|
@wbuf << i @wbuf << s
if @wbuf.size > 2048 then yield if @wbuf.size > 2048
yield
end
end end
yield unless @wbuf.empty? yield unless @wbuf.empty?
end end
@ -759,7 +754,7 @@ module Net
end end
def <<( str ) def <<( str )
call_block str, &@block if @block call_block(str, &@block) if @block
end end
private private

View file

@ -21,11 +21,15 @@ This module provides your program the functions to send internet
mail via SMTP, Simple Mail Transfer Protocol. For details of mail via SMTP, Simple Mail Transfer Protocol. For details of
SMTP itself, refer [RFC2821] ((<URL:http://www.ietf.org/rfc/rfc2821.txt>)). SMTP itself, refer [RFC2821] ((<URL:http://www.ietf.org/rfc/rfc2821.txt>)).
== What This Module is NOT? == What is NOT This Module?
This module does NOT provide the functions to compose internet This module does NOT provide functions to compose internet mails.
mail. You must create it by yourself. For details of internet mail You must create it by yourself. If you want better mail support,
format, see [RFC2822] ((<URL:http://www.ietf.org/rfc/rfc2822.txt>)). try RubyMail or TMail. You can get both libraries from RAA.
((<URL:http://www.ruby-lang.org/en/raa.html>))
FYI: official documentation of internet mail is:
[RFC2822] ((<URL:http://www.ietf.org/rfc/rfc2822.txt>)).
== Examples == Examples
@ -34,11 +38,11 @@ format, see [RFC2822] ((<URL:http://www.ietf.org/rfc/rfc2822.txt>)).
You must open connection to SMTP server before sending mails. You must open connection to SMTP server before sending mails.
First argument is the address of SMTP server, and second argument First argument is the address of SMTP server, and second argument
is port number. Using SMTP.start with block is the most simple way is port number. Using SMTP.start with block is the most simple way
to do it. SMTP Connection is closed automatically after block is to do it. SMTP connection is closed automatically after block is
executed. executed.
require 'net/smtp' require 'net/smtp'
Net::SMTP.start( 'your.smtp.server', 25 ) {|smtp| Net::SMTP.start('your.smtp.server', 25) {|smtp|
# use smtp object only in this block # use smtp object only in this block
} }
@ -48,10 +52,7 @@ for you.
Then you can send mail. Then you can send mail.
require 'net/smtp' mail_text = <<END_OF_MAIL
Net::SMTP.start( 'your.smtp.server', 25 ) {|smtp|
smtp.send_mail <<EndOfMail, 'your@mail.address', 'to@some.domain'
From: Your Name <your@mail.address> From: Your Name <your@mail.address>
To: Dest Address <to@some.domain> To: Dest Address <to@some.domain>
Subject: test mail Subject: test mail
@ -59,7 +60,13 @@ Then you can send mail.
Message-Id: <unique.message.id.string@some.domain> Message-Id: <unique.message.id.string@some.domain>
This is test mail. This is test mail.
EndOfMail END_OF_MAIL
require 'net/smtp'
Net::SMTP.start('your.smtp.server', 25) {|smtp|
smtp.send_mail mail_text,
'your@mail.address',
'his_addess@example.com'
} }
=== Closing Session === Closing Session
@ -70,24 +77,24 @@ closes session automatically. I strongly recommend later one. It is
more beautiful and simple. more beautiful and simple.
# using SMTP#finish # using SMTP#finish
smtp = Net::SMTP.start( 'your.smtp.server', 25 ) smtp = Net::SMTP.start('your.smtp.server', 25)
smtp.send_mail mail_string, 'from@address', 'to@address' smtp.send_mail mail_string, 'from@address', 'to@address'
smtp.finish smtp.finish
# using block form of SMTP.start # using block form of SMTP.start
Net::SMTP.start( 'your.smtp.server', 25 ) {|smtp| Net::SMTP.start('your.smtp.server', 25) {|smtp|
smtp.send_mail mail_string, 'from@address', 'to@address' smtp.send_mail mail_string, 'from@address', 'to@address'
} }
=== Sending Mails from Any Sources === Sending Mails From non-String Sources
In an example above I sent mail from String (here document literal). In an example above I has sent mail from String (here document literal).
SMTP#send_mail accepts any objects which has "each" method SMTP#send_mail accepts any objects which has "each" method
like File and Array. like File and Array.
require 'net/smtp' require 'net/smtp'
Net::SMTP.start( 'your.smtp.server', 25 ) {|smtp| Net::SMTP.start('your.smtp.server', 25) {|smtp|
File.open( 'Mail/draft/1' ) {|f| File.open('Mail/draft/1') {|f|
smtp.send_mail f, 'your@mail.address', 'to@some.domain' smtp.send_mail f, 'your@mail.address', 'to@some.domain'
} }
} }
@ -248,13 +255,13 @@ module Net
conn_command conn_command
begin begin
if @esmtp then if @esmtp
command().ehlo helo command().ehlo helo
else else
command().helo helo command().helo helo
end end
rescue ProtocolError rescue ProtocolError
if @esmtp then if @esmtp
@esmtp = false @esmtp = false
command().error_ok command().error_ok
retry retry
@ -263,14 +270,12 @@ module Net
end end
end end
if user or secret then if user or secret
(user and secret) or raise ArgumentError, 'both of account and password are required'\
raise ArgumentError, 'both of account and password are required' unless user and secret
mid = 'auth_' + (authtype || 'cram_md5').to_s mid = 'auth_' + (authtype || 'cram_md5').to_s
command().respond_to? mid or raise ArgumentError, "wrong auth type #{authtype}"\
raise ArgumentError, "wrong auth type #{authtype.to_s}" unless command().respond_to?(mid)
command().__send__ mid, user, secret command().__send__ mid, user, secret
end end
end end
@ -289,7 +294,7 @@ module Net
def send_mail( mailsrc, from_addr, *to_addrs ) def send_mail( mailsrc, from_addr, *to_addrs )
do_ready from_addr, to_addrs.flatten do_ready from_addr, to_addrs.flatten
command().write_mail(mailsrc) command().write_mail mailsrc
end end
alias sendmail send_mail alias sendmail send_mail
@ -304,7 +309,7 @@ module Net
def do_ready( from_addr, to_addrs ) def do_ready( from_addr, to_addrs )
raise ArgumentError, 'mail destination does not given' if to_addrs.empty? raise ArgumentError, 'mail destination does not given' if to_addrs.empty?
command().mailfrom from_addr command().mailfrom from_addr
command().rcpt(to_addrs) command().rcpt to_addrs
end end
end end
@ -344,18 +349,18 @@ module Net
# "CRAM-MD5" authentication [RFC2195] # "CRAM-MD5" authentication [RFC2195]
def auth_cram_md5( user, secret ) def auth_cram_md5( user, secret )
atomic { atomic {
rep = getok( 'AUTH CRAM-MD5', ContinueCode ) rep = getok('AUTH CRAM-MD5', ContinueCode)
challenge = rep.msg.split(' ')[1].unpack('m')[0] challenge = rep.msg.split(/ /)[1].unpack('m')[0]
secret = Digest::MD5.digest(secret) if secret.size > 64 secret = Digest::MD5.digest(secret) if secret.size > 64
isecret = secret + "\0" * (64 - secret.size) isecret = secret + "\0" * (64 - secret.size)
osecret = isecret.dup osecret = isecret.dup
0.upto( 63 ) do |i| 0.upto(63) do |i|
isecret[i] ^= 0x36 isecret[i] ^= 0x36
osecret[i] ^= 0x5c osecret[i] ^= 0x5c
end end
tmp = Digest::MD5.digest( isecret + challenge ) tmp = Digest::MD5.digest(isecret + challenge)
tmp = Digest::MD5.hexdigest( osecret + tmp ) tmp = Digest::MD5.hexdigest(osecret + tmp)
getok [user + ' ' + tmp].pack('m').chomp getok [user + ' ' + tmp].pack('m').chomp
} }
@ -416,14 +421,14 @@ module Net
end end
klass ||= UnknownCode klass ||= UnknownCode
Response.new( klass, stat, arr.join('') ) Response.new(klass, stat, arr.join(''))
end end
def read_reply def read_reply
arr = [] arr = []
while true do while true
str = @socket.readline str = @socket.readline
break unless str[3] == ?- # ex: "210-..." break unless str[3] == ?- # "210-PIPELINING"
arr.push str arr.push str
end end
arr.push str arr.push str