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: synchronize document with source code.

* lib/net/pop.rb: ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
aamine 2003-07-02 02:39:53 +00:00
parent c20ecb1ba4
commit f261bdf66c
3 changed files with 324 additions and 170 deletions

View file

@ -1,3 +1,9 @@
Wed Jul 2 11:45:34 2003 Minero Aoki <aamine@loveruby.net>
* lib/net/smtp.rb: synchronize document with source code.
* lib/net/pop.rb: ditto.
Wed Jul 2 11:39:50 2003 Minero Aoki <aamine@loveruby.net>
* lib/net/smtp.rb: unify SMTP and SMTPCommand.

View file

@ -18,7 +18,7 @@ $Id$
== What is This Module?
This module provides your program the functions to retrieve
This module provides your program the function to retrieve
mails via POP3, Post Office Protocol version 3. For details
of POP3, refer [RFC1939] ((<URL:http://www.ietf.org/rfc/rfc1939.txt>)).
@ -32,22 +32,22 @@ Replace 'pop3.server.address' your POP3 server address.
require 'net/pop'
pop = Net::POP3.new('pop3.server.address', 110)
pop.start('YourAccount', 'YourPassword') ###
if pop.mails.empty? then
pop = Net::POP3.new('pop.example.com', 110)
pop.start('YourAccount', 'YourPassword') # (1)
if pop.mails.empty?
puts 'no mail.'
else
i = 0
pop.each_mail do |m| # or "pop.mails.each ..."
File.open('inbox/' + i.to_s, 'w') {|f|
f.write m.pop
pop.each_mail do |m| # or "pop.mails.each ..." # (2)
File.open("inbox/#{i}", 'w') {|f|
f.write m.pop
}
m.delete
i += 1
end
puts "#{pop.mails.size} mails popped."
end
pop.finish ###
pop.finish # (3)
(1) call Net::POP3#start and start POP session
(2) access mails by using POP3#each_mail and/or POP3#mails
@ -63,40 +63,40 @@ alternates POP3.new, POP3#start and POP3#finish.
require 'net/pop'
Net::POP3.start('pop3.server.address', 110)
'YourAccount', 'YourPassword')
if pop.mails.empty?
puts 'no mail.'
else
i = 0
pop.each_mail do |m| # or "pop.mails.each ..."
File.open('inbox/' + i.to_s, 'w') {|f|
f.write m.pop
}
m.delete
i += 1
end
puts "#{pop.mails.size} mails popped."
Net::POP3.start('pop.example.com', 110,
'YourAccount', 'YourPassword') {|pop|
if pop.mails.empty?
puts 'no mail.'
else
i = 0
pop.each_mail do |m| # or "pop.mails.each ..."
File.open("inbox/#{i}", 'w') {|f|
f.write m.pop
}
m.delete
i += 1
end
puts "#{pop.mails.size} mails popped."
end
}
POP3#delete_all alternates #each_mail and m.delete.
require 'net/pop'
Net::POP3.start('pop3.server.address', 110,
Net::POP3.start('pop.example.com', 110,
'YourAccount', 'YourPassword') {|pop|
if pop.mails.empty?
puts 'no mail.'
else
i = 0
pop.delete_all do |m|
File.open('inbox/' + i.to_s, 'w') {|f|
f.write m.pop
}
i += 1
end
if pop.mails.empty?
puts 'no mail.'
else
i = 1
pop.delete_all do |m|
File.open("inbox/#{i}", 'w') {|f|
f.write m.pop
}
i += 1
end
end
}
And here is more shorter example.
@ -104,24 +104,29 @@ And here is more shorter example.
require 'net/pop'
i = 0
Net::POP3.delete_all('pop3.server.address', 110,
Net::POP3.delete_all('pop.example.com', 110,
'YourAccount', 'YourPassword') do |m|
File.open('inbox/' + i.to_s, 'w') {|f|
f.write m.pop
File.open("inbox/#{i}", 'w') {|f|
f.write m.pop
}
i += 1
end
=== Writing to File directly
=== Memory Space Issue
All examples above get mail as one big string.
This example does not create such one.
require 'net/pop'
Net::POP3.delete_all('pop3.server.address', 110,
i = 1
Net::POP3.delete_all('pop.example.com', 110,
'YourAccount', 'YourPassword') do |m|
File.open('inbox', 'w') {|f|
m.pop f ####
File.open("inbox/#{i}", 'w') {|f|
m.pop do |chunk| # get a message little by little.
f.write chunk
end
i += 1
}
end
@ -134,12 +139,12 @@ You can use utility method, Net::POP3.APOP(). Example:
require 'net/pop'
# Use APOP authentication if $isapop == true
pop = Net::POP3.APOP($isapop).new('apop.server.address', 110)
pop = Net::POP3.APOP($is_apop).new('apop.example.com', 110)
pop.start(YourAccount', 'YourPassword') {|pop|
# Rest code is same.
# Rest code is same.
}
=== Fetch Only Selected Mail Using POP UIDL Function
=== Fetch Only Selected Mail Using `UIDL' POP Command
If your POP server provides UIDL function,
you can pop only selected mails from POP server.
@ -149,7 +154,7 @@ e.g.
# determine if we need pop this mail...
end
Net::POP3.start('pop.server', 110,
Net::POP3.start('pop.example.com', 110,
'Your account', 'Your password') {|pop|
pop.mails.select {|m| need_pop?(m.unique_id) }.each do |m|
do_something(m.pop)
@ -175,53 +180,53 @@ Normally unique-id is a hash of the message.
# Typical usage
Net::POP3.start(addr, port, account, password) {|pop|
pop.each_mail do |m|
file.write m.pop
m.delete
end
pop.each_mail do |m|
file.write m.pop
m.delete
end
}
: APOP( is_apop )
returns Net::APOP class object if IS_APOP is true.
returns Net::POP3 class object if false.
Use this method like:
returns Net::APOP class object if IS_APOP.
Else, IS_APOP. Use this method like:
# Example 1
pop = Net::POP3::APOP($isapop).new( addr, port )
pop = Net::POP3::APOP($is_apop).new(addr, port)
# Example 2
Net::POP3::APOP($isapop).start( addr, port ) {|pop|
....
Net::POP3::APOP($is_apop).start(addr, port) {|pop|
....
}
: foreach( address, port = 110, account, password, isapop = false ) {|mail| .... }
: foreach( address, port = 110, account, password, isapop = false ) {|popmail| .... }
starts POP3 protocol and iterates for each POPMail object.
This method equals to:
Net::POP3.start( address, port, account, password ) {|pop|
pop.each_mail do |m|
yield m
end
Net::POP3.start(address, port, account, password) {|pop|
pop.each_mail do |m|
yield m
end
}
This method raises POPAuthenticationError if authentication is failed.
# Typical usage
Net::POP3.foreach( 'your.pop.server', 110,
'YourAccount', 'YourPassword' ) do |m|
Net::POP3.foreach('pop.example.com', 110,
'YourAccount', 'YourPassword') do |m|
file.write m.pop
m.delete if $DELETE
end
: delete_all( address, port = 110, account, password, isapop = false )
: delete_all( address, port = 110, account, password, isapop = false ) {|mail| .... }
: delete_all( address, port = 110, account, password, isapop = false ) {|popmail| .... }
starts POP3 session and delete all mails.
If block is given, iterates for each POPMail object before delete.
This method raises POPAuthenticationError if authentication is failed.
# Example
Net::POP3.delete_all( addr, nil, 'YourAccount', 'YourPassword' ) do |m|
m.pop file
Net::POP3.delete_all('pop.example.com', 110,
'YourAccount', 'YourPassword') do |m|
file.write m.pop
end
: auth_only( address, port = 110, account, password, isapop = false )
@ -231,11 +236,13 @@ Normally unique-id is a hash of the message.
This method must not be called while POP3 session is opened.
This method raises POPAuthenticationError if authentication is failed.
# Example
Net::POP3.auth_only( 'your.pop3.server',
nil, # using default (110)
'YourAccount',
'YourPassword' )
# Example 1: normal POP3
Net::POP3.auth_only('pop.example.com', 110,
'YourAccount', 'YourPassword')
# Example 2: APOP
Net::POP3.auth_only('pop.example.com', 110,
'YourAccount', 'YourPassword', true)
=== Instance Methods
@ -249,6 +256,7 @@ Normally unique-id is a hash of the message.
This method raises POPAuthenticationError if authentication is failed.
: started?
: active? OBSOLETE
true if POP3 session is started.
: address
@ -283,13 +291,17 @@ Normally unique-id is a hash of the message.
an array of Net::POPMail objects.
This array is renewed when session restarts.
This method raises POPError if any problem happend.
This method raises POPError if any problem happened.
: each_mail {|popmail| .... }
: each {|popmail| .... }
is equals to "pop3.mails.each"
is equals to:
pop3.mails.each do |popmail|
....
end
This method raises POPError if any problem happend.
This method raises POPError if any problem happened.
: delete_all
: delete_all {|popmail| .... }
@ -299,16 +311,31 @@ Normally unique-id is a hash of the message.
# Example
n = 1
pop.delete_all do |m|
File.open("inbox/#{n}") {|f| f.write m.pop }
File.open("inbox/#{n}") {|f|
f.write m.pop
}
n += 1
end
This method raises POPError if any problem happend.
This method raises POPError if any problem happened.
: reset
reset the session. All "deleted mark" are removed.
This method raises POPError if any problem happend.
This method raises POPError if any problem happened.
: set_debug_output( output )
WARNING: This method causes serious security hole.
Use this method for only debugging.
set output stream for debugging.
# Example
pop = Net::POP.new(addr, port)
pop.set_debug_output $stderr
pop.start(account, passwd) {
....
}
== class Net::APOP
@ -327,58 +354,101 @@ A class of mail which exists on POP server.
=== Instance Methods
: pop( dest = '' )
This method fetches a mail and write to 'dest' using '<<' method.
: pop
This method fetches a message as a String.
This method raises POPError if any problem happend.
This method may raise POPError.
# Typical usage
allmails = nil
POP3.start( 'your.pop3.server', 110,
'YourAccount, 'YourPassword' ) {|pop|
allmails = pop.mails.collect {|popmail| popmail.pop }
# Example
POP3.start('pop.example.com', 110,
'YourAccount, 'YourPassword') {|pop|
n = 1
pop.mails.each do |popmail|
File.open("inbox/#{n}", 'w') {|f|
f.write popmail.pop ####
}
popmail.delete
n += 1
end
}
: pop {|str| .... }
gives the block part strings of a mail.
: pop {|chunk| .... }
gives the block parts of the message.
This method raises POPError if any problem happend.
This method may raise POPError.
# Typical usage
POP3.start( 'localhost', 110 ) {|pop3|
pop3.each_mail do |m|
m.pop do |str|
# do anything
# Example
POP3.start('pop.example.com', 110,
'YourAccount, 'YourPassword') {|pop|
n = 1
pop.mails.each do |popmail|
File.open("inbox/#{n}", 'w') {|f|
popmail.pop do |chunk| ####
f.write chunk
end
end
}
n += 1
end
}
: header
fetches only mail header.
fetches the message header.
This method raises POPError if any problem happend.
This method may raise POPError.
: top( lines )
fetches mail header and LINES lines of body.
fetches the message header and LINES lines of body.
This method raises POPError if any problem happend.
This method may raise POPError.
: delete
deletes mail on server.
deletes the message on the POP server.
This method raises POPError if any problem happend.
This method may raise POPError.
# Example
POP3.start('pop.example.com', 110,
'YourAccount, 'YourPassword') {|pop|
n = 1
pop.mails.each do |popmail|
File.open("inbox/#{n}", 'w') {|f|
f.write popmail.pop
}
popmail.delete ####
n += 1
end
}
: length
: size
mail size (bytes)
the length of the message (in octets).
: deleted?
true if mail was deleted
true if mail was deleted.
: unique_id
returns an unique-id of the message.
Normally unique-id is a hash of the message.
returns the unique-id of the message.
Normally unique-id is a hash string of the message.
This method raises POPError if any problem happend.
This method may raise POPError.
== POP3 Related Exception Classes
: POPError
POP3 protocol error (reply code "-ERR", except authentication).
ancestors: ProtocolError (obsolete)
: POPAuthenticationError
POP3 authentication error.
ancestors: POPError, ProtoAuthError (obsolete), ProtocolError (obsolete)
: POPBadResponse
Unexpected response got from server.
ancestors: POPError
=end

View file

@ -34,9 +34,9 @@ FYI: official documentation of internet mail is:
== Examples
=== Sending Mail
=== Sending Message
You must open connection to SMTP server before sending mails.
You must open connection to SMTP server before sending messages.
First argument is the address of SMTP server, and second argument
is port number. Using SMTP.start with block is the most simple way
to do it. SMTP connection is closed automatically after block is
@ -44,61 +44,51 @@ executed.
require 'net/smtp'
Net::SMTP.start('your.smtp.server', 25) {|smtp|
# use SMTP object only in this block
# use a SMTP object only in this block
}
Replace 'your.smtp.server' by your SMTP server. Normally
your system manager or internet provider is supplying a server
for you.
Then you can send mail.
Then you can send messages.
mail_text = <<END_OF_MAIL
msgstr = <<END_OF_MESSAGE
From: Your Name <your@mail.address>
To: Dest Address <to@some.domain>
Subject: test mail
To: Destination Address <someone@example.com>
Subject: test message
Date: Sat, 23 Jun 2001 16:26:43 +0900
Message-Id: <unique.message.id.string@some.domain>
Message-Id: <unique.message.id.string@example.com>
This is test mail.
END_OF_MAIL
This is a test message.
END_OF_MESSAGE
require 'net/smtp'
Net::SMTP.start('your.smtp.server', 25) {|smtp|
smtp.send_mail mail_text,
'your@mail.address',
'his_addess@example.com'
smtp.send_message msgstr,
'your@mail.address',
'his_addess@example.com'
}
=== Closing Session
You MUST close SMTP session after sending mails, by calling #finish
method. You can also use block form of SMTP.start/SMTP#start, which
closes session automatically. I strongly recommend later one. It is
more beautiful and simple.
You MUST close SMTP session after sending messages, by calling #finish
method:
# using SMTP#finish
smtp = Net::SMTP.start('your.smtp.server', 25)
smtp.send_mail mail_string, 'from@address', 'to@address'
smtp.send_message msgstr, 'from@address', 'to@address'
smtp.finish
You can also use block form of SMTP.start/SMTP#start. They closes
SMTP session automatically:
# using block form of SMTP.start
Net::SMTP.start('your.smtp.server', 25) {|smtp|
smtp.send_mail mail_string, 'from@address', 'to@address'
smtp.send_message msgstr, 'from@address', 'to@address'
}
=== Sending Mails From non-String Sources
In an example above I has sent mail from String (here document literal).
SMTP#send_mail accepts any objects which has "each" method
like File and Array.
require 'net/smtp'
Net::SMTP.start('your.smtp.server', 25) {|smtp|
File.open('Mail/draft/1') {|f|
smtp.send_mail f, 'your@mail.address', 'to@some.domain'
}
}
I strongly recommend this scheme. This form is more simple and robust.
=== HELO domain
@ -113,8 +103,10 @@ the SMTP session by inspecting HELO domain.
=== SMTP Authentication
net/smtp supports three authentication scheme.
The Net::SMTP class supports three authentication schemes;
PLAIN, LOGIN and CRAM MD5. (SMTP Authentication: [RFC2554])
To use SMTP authentication, pass extra arguments to
SMTP.start/SMTP#start methods.
# PLAIN
Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain',
@ -127,24 +119,34 @@ PLAIN, LOGIN and CRAM MD5. (SMTP Authentication: [RFC2554])
Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain',
'Your Account', 'Your Password', :cram_md5)
== class Net::SMTP
=== Class Methods
: new( address, port = 25 )
creates a new Net::SMTP object.
This method does not open TCP connection.
: start( address, port = 25, helo_domain = 'localhost.localdomain', account = nil, password = nil, authtype = nil )
: start( address, port = 25, helo_domain = 'localhost.localdomain', account = nil, password = nil, authtype = nil ) {|smtp| .... }
is equal to
is equal to:
Net::SMTP.new(address,port).start(helo_domain,account,password,authtype)
# example
Net::SMTP.start( 'your.smtp.server' ) {
smtp.send_mail mail_string, 'from@mail.address', 'dest@mail.address'
Net::SMTP.start('your.smtp.server') {
smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
}
This method may raise:
* Net::SMTPAuthenticationError
* Net::SMTPServerBusy
* Net::SMTPSyntaxError
* Net::SMTPFatalError
* Net::SMTPUnknownError
* IOError
* TimeoutError
=== Instance Methods
: start( helo_domain = <local host name>, account = nil, password = nil, authtype = nil )
@ -160,7 +162,18 @@ PLAIN, LOGIN and CRAM MD5. (SMTP Authentication: [RFC2554])
authentication by using AUTH command. AUTHTYPE is an either of
:login, :plain, and :cram_md5.
This method may raise:
* Net::SMTPAuthenticationError
* Net::SMTPServerBusy
* Net::SMTPSyntaxError
* Net::SMTPFatalError
* Net::SMTPUnknownError
* IOError
* TimeoutError
: started?
: active? OBSOLETE
true if SMTP session is started.
: esmtp?
@ -183,63 +196,128 @@ PLAIN, LOGIN and CRAM MD5. (SMTP Authentication: [RFC2554])
: read_timeout
: read_timeout=(n)
seconds to wait until reading one block (by one read(1) call).
seconds to wait until reading one block (by one read(2) call).
If SMTP object cannot open a conection in this seconds,
it raises TimeoutError exception.
: finish
finishes SMTP session.
If SMTP session had not started, raises an IOError.
If SMTP session timed out, raises TimeoutError.
: send_mail( mailsrc, from_addr, *to_addrs )
This method sends MAILSRC as mail. A SMTP object read strings
from MAILSRC by calling "each" iterator, with converting them
into CRLF ("\r\n") terminated string when write.
: send_message( msgstr, from_addr, *dest_addrs )
: send_mail( msgstr, from_addr, *dest_addrs )
: sendmail( msgstr, from_addr, *dest_addrs ) OBSOLETE
sends a String MSGSTR. If a single CR ("\r") or LF ("\n") found
in the MEGSTR, converts it to the CR LF pair. You cannot send a
binary message with this class.
FROM_ADDR must be a String, representing source mail address.
TO_ADDRS must be Strings or an Array of Strings, representing
destination mail addresses.
# example
Net::SMTP.start( 'your.smtp.server' ) {|smtp|
smtp.send_mail mail_string,
'from@mail.address',
'dest@mail.address' 'dest2@mail.address'
Net::SMTP.start('smtp.example.com') {|smtp|
smtp.send_message msgstr,
'from@example.com',
['dest@example.com', 'dest2@example.com']
}
: ready( from_addr, *to_addrs ) {|adapter| .... }
This method stands by the SMTP object for sending mail and
gives adapter object to the block. ADAPTER has these 5 methods:
This method may raise:
puts print printf write <<
* Net::SMTPServerBusy
* Net::SMTPSyntaxError
* Net::SMTPFatalError
* Net::SMTPUnknownError
* IOError
* TimeoutError
: open_message_stream( from_addr, *dest_addrs ) {|stream| .... }
: ready( from_addr, *dest_addrs ) {|stream| .... } OBSOLETE
opens a message writer stream and gives it to the block.
STREAM is valid only in the block, and has these methods:
: puts(str = '')
outputs STR and CR LF.
: print(str)
outputs STR.
: printf(fmt, *args)
outputs sprintf(fmt,*args).
: write(str)
outputs STR and returns the length of written bytes.
: <<(str)
outputs STR and returns self.
If a single CR ("\r") or LF ("\n") found in the message,
converts it to the CR LF pair. You cannot send a binary
message with this class.
FROM_ADDR must be a String, representing source mail address.
TO_ADDRS must be Strings or an Array of Strings, representing
destination mail addresses.
# example
Net::SMTP.start( 'your.smtp.server', 25 ) {|smtp|
smtp.ready( 'from@mail.addr', 'dest@mail.addr' ) {|f|
f.puts 'From: aamine@loveruby.net'
f.puts 'To: someone@somedomain.org'
f.puts 'Subject: test mail'
f.puts
f.puts 'This is test mail.'
}
Net::SMTP.start('smtp.example.com', 25) {|smtp|
smtp.open_message_stream('from@example.com', ['dest@example.com']) {|f|
f.puts 'From: from@example.com'
f.puts 'To: dest@example.com'
f.puts 'Subject: test message'
f.puts
f.puts 'This is a test message.'
}
}
== Exceptions
This method may raise:
SMTP objects raise these exceptions:
* Net::SMTPServerBusy
* Net::SMTPSyntaxError
* Net::SMTPFatalError
* Net::SMTPUnknownError
* IOError
* TimeoutError
: Net::ProtoSyntaxError
Syntax error (errno.500)
: Net::ProtoFatalError
Fatal error (errno.550)
: Net::ProtoUnknownError
Unknown error. (is probably bug)
: Net::ProtoServerBusy
Temporal error (errno.420/450)
: set_debug_output( output )
WARNING: This method causes serious security holes.
Use this method for only debugging.
set an output stream for debug logging.
You must call this before #start.
# example
smtp = Net::SMTP.new(addr, port)
smtp.set_debug_output $stderr
smtp.start {
....
}
== SMTP Related Exception Classes
: Net::SMTPAuthenticationError
SMTP authentication error.
ancestors: SMTPError, ProtoAuthError (obsolete), ProtocolError (obsolete)
: Net::SMTPServerBusy
Temporal error; error number 420/450.
ancestors: SMTPError, ProtoServerError (obsolete), ProtocolError (obsolete)
: Net::SMTPSyntaxError
SMTP command syntax error (error number 500)
ancestors: SMTPError, ProtoSyntaxError (obsolete), ProtocolError (obsolete)
: Net::SMTPFatalError
Fatal error (error number 5xx, except 500)
ancestors: SMTPError, ProtoFatalError (obsolete), ProtocolError (obsolete)
: Net::SMTPUnknownError
Unexpected reply code returned from server
(might be a bug of this library).
ancestors: SMTPError, ProtoUnkownError (obsolete), ProtocolError (obsolete)
=end