From d9c41de9ccd3a1f262b22ddb0c705038c97beef5 Mon Sep 17 00:00:00 2001 From: gsinclair Date: Sun, 9 May 2004 14:42:43 +0000 Subject: * lib/net/ftp.rb: ported documentation improvement from 1.8 branch * lib/net/imap.rb: ditto * lib/net/pop.rb: ditto * lib/net/smtp.rb: ditto * lib/net/telnet.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6284 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/net/smtp.rb | 372 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 201 insertions(+), 171 deletions(-) (limited to 'lib/net/smtp.rb') diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb index b3b1f108ab..5becf2b36b 100644 --- a/lib/net/smtp.rb +++ b/lib/net/smtp.rb @@ -1,10 +1,12 @@ # = net/smtp.rb +# +# Copyright (c) 1999-2004 Yukihiro Matsumoto. # -#-- -# Copyright (C) 1999-2004 Yukihiro Matsumoto -# Copyright (C) 1999-2004 Minero Aoki +# Copyright (c) 1999-2004 Minero Aoki. # -# written and maintained by Minero Aoki +# Written & maintained by Minero Aoki . +# +# Documented by William Webber and Minero Aoki. # # This program is free software. You can re-distribute and/or # modify this program under the same terms as Ruby itself. @@ -13,140 +15,8 @@ # http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=net%2Fsmtp.rb # # $Id$ -#++ -# -# == What is This Library? -# -# This library provides functionality to send internet -# mail via SMTP, the Simple Mail Transfer Protocol. For details of -# SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt). -# -# == What is This Library NOT? -# -# This library does NOT provide functions to compose internet mails. -# You must create them by yourself. If you want better mail support, -# try RubyMail or TMail. You can get both libraries from RAA. -# (http://www.ruby-lang.org/en/raa.html) -# -# FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt). -# -# == Examples -# -# === Sending Messages -# -# You must open a connection to an SMTP server before sending messages. -# The first argument is the address of your SMTP server, and the second -# argument is the port number. Using SMTP.start with a block is the simplest -# way to do this. This way, the SMTP connection is closed automatically -# after the block is executed. -# -# require 'net/smtp' -# Net::SMTP.start('your.smtp.server', 25) {|smtp| -# # use the SMTP object smtp only in this block -# } -# -# Replace 'your.smtp.server' with your SMTP server. Normally -# your system manager or internet provider supplies a server -# for you. -# -# Then you can send messages. -# -# msgstr = < -# To: Destination Address -# Subject: test message -# Date: Sat, 23 Jun 2001 16:26:43 +0900 -# Message-Id: -# -# This is a test message. -# END_OF_MESSAGE -# -# require 'net/smtp' -# Net::SMTP.start('your.smtp.server', 25) {|smtp| -# smtp.send_message msgstr, -# 'your@mail.address', -# 'his_addess@example.com' -# } -# -# === Closing the Session -# -# You MUST close the SMTP session after sending messages, by calling -# the #finish method: -# -# # using SMTP#finish -# smtp = Net::SMTP.start('your.smtp.server', 25) -# smtp.send_message msgstr, 'from@address', 'to@address' -# smtp.finish -# -# You can also use the block form of SMTP.start/SMTP#start. This closes -# the SMTP session automatically: -# -# # using block form of SMTP.start -# Net::SMTP.start('your.smtp.server', 25) {|smtp| -# smtp.send_message msgstr, 'from@address', 'to@address' -# } -# -# I strongly recommend this scheme. This form is simpler and more robust. -# -# === HELO domain -# -# In almost all situations, you must provide a third argument -# to SMTP.start/SMTP#start. This is the domain name which you are on -# (the host to send mail from). It is called the "HELO domain". -# The SMTP server will judge whether it should send or reject -# the SMTP session by inspecting the HELO domain. -# -# Net::SMTP.start('your.smtp.server', 25, -# 'mail.from.domain') {|smtp| ... } -# -# === SMTP Authentication -# -# 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. Use in conjunction with STARTTLS to -# prevent authentication information passing in the clear. -# -# # PLAIN -# Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain', -# 'Your Account', 'Your Password', :plain) -# # LOGIN -# Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain', -# 'Your Account', 'Your Password', :login) -# -# # CRAM MD5 -# Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain', -# 'Your Account', 'Your Password', :cram_md5) -# -# === STARTTLS support # -# The Net::SMTP class supports STARTTLS. -# -# # Per Instance STARTTLS -# smtp = Net::SMTP.new('smtp.example.com',25) -# smtp.enable_tls(verify, certs) if $use_tls #(1) -# smtp.start('your host','username','password') { |s| -# s.send_message msgstr, -# 'your@mail.address', -# 'recipient@example.com' -# } -# smtp.finish -# -# 1. +verify+ tells the openssl library how to verify the server -# certificate. Defaults to OpenSSL::SSL::VERIFY_PEER -# +certs+ is a file or directory holding CA certs to use to verify the -# server cert; Defaults to nil. -# -# -# # USE STARTTLS for all subsequent instances -# Net::SMTP.enable_tls -# # We will now use starttls for all connections. -# Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain', -# 'Your Account', 'Your Password', :plain) {|smtp| -# smtp.send_message msgstr, -# 'your@mail.address', -# 'his_addess@example.com' -# } +# See Net::SMTP for documentation. # require 'net/protocol' @@ -157,7 +27,7 @@ begin rescue LoadError end -module Net # :nodoc: +module Net # Module mixed in to all SMTP error classes module SMTPError @@ -191,14 +61,114 @@ module Net # :nodoc: end # - # Class providing SMTP client functionality. + # = Net::SMTP # - # See documentation for the file smtp.rb for examples of usage. + # == What is This Library? + # + # This library provides functionality to send internet + # mail via SMTP, the Simple Mail Transfer Protocol. For details of + # SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt). + # + # == What is This Library NOT? + # + # This library does NOT provide functions to compose internet mails. + # You must create them by yourself. If you want better mail support, + # try RubyMail or TMail. You can get both libraries from RAA. + # (http://www.ruby-lang.org/en/raa.html) + # + # FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt). + # + # == Examples + # + # === Sending Messages + # + # You must open a connection to an SMTP server before sending messages. + # The first argument is the address of your SMTP server, and the second + # argument is the port number. Using SMTP.start with a block is the simplest + # way to do this. This way, the SMTP connection is closed automatically + # after the block is executed. + # + # require 'net/smtp' + # Net::SMTP.start('your.smtp.server', 25) do |smtp| + # # Use the SMTP object smtp only in this block. + # end + # + # Replace 'your.smtp.server' with your SMTP server. Normally + # your system manager or internet provider supplies a server + # for you. + # + # Then you can send messages. + # + # msgstr = < + # To: Destination Address + # Subject: test message + # Date: Sat, 23 Jun 2001 16:26:43 +0900 + # Message-Id: + # + # This is a test message. + # END_OF_MESSAGE + # + # require 'net/smtp' + # Net::SMTP.start('your.smtp.server', 25) do |smtp| + # smtp.send_message msgstr, + # 'your@mail.address', + # 'his_addess@example.com' + # end + # + # === Closing the Session + # + # You MUST close the SMTP session after sending messages, by calling + # the #finish method: + # + # # using SMTP#finish + # smtp = Net::SMTP.start('your.smtp.server', 25) + # smtp.send_message msgstr, 'from@address', 'to@address' + # smtp.finish + # + # You can also use the block form of SMTP.start/SMTP#start. This closes + # the SMTP session automatically: + # + # # using block form of SMTP.start + # Net::SMTP.start('your.smtp.server', 25) do |smtp| + # smtp.send_message msgstr, 'from@address', 'to@address' + # end + # + # I strongly recommend this scheme. This form is simpler and more robust. + # + # === HELO domain + # + # In almost all situations, you must provide a third argument + # to SMTP.start/SMTP#start. This is the domain name which you are on + # (the host to send mail from). It is called the "HELO domain". + # The SMTP server will judge whether it should send or reject + # the SMTP session by inspecting the HELO domain. + # + # Net::SMTP.start('your.smtp.server', 25, + # 'mail.from.domain') { |smtp| ... } + # + # === SMTP Authentication + # + # 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. + # + # # PLAIN + # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain', + # 'Your Account', 'Your Password', :plain) + # # LOGIN + # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain', + # 'Your Account', 'Your Password', :login) + # + # # CRAM MD5 + # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain', + # 'Your Account', 'Your Password', :cram_md5) # class SMTP Revision = %q$Revision$.split[1] - + # The default SMTP port, port 25. def SMTP.default_port 25 @@ -238,10 +208,17 @@ module Net # :nodoc: @certs end - # Creates a new Net::SMTP object. +address+ is the hostname - # or ip address of your SMTP server. +port+ is the port to - # connect to; it defaults to port 25. - # This method does not open the TCP connection. + # + # Creates a new Net::SMTP object. + # + # +address+ is the hostname or ip address of your SMTP + # server. +port+ is the port to connect to; it defaults to + # port 25. + # + # This method does not open the TCP connection. You can use + # SMTP.start instead of SMTP.new if you want to do everything + # at once. Otherwise, follow SMTP.new with SMTP#start. + # def initialize(address, port = nil) @address = address @port = (port || SMTP.default_port) @@ -267,11 +244,13 @@ module Net # :nodoc: @esmtp end + # # Set whether to use ESMTP or not. This should be done before # calling #start. Note that if #start is called in ESMTP mode, # and the connection fails due to a ProtocolError, the SMTP # object will automatically switch to plain SMTP mode and # retry (but not vice versa). + # def esmtp=(bool) @esmtp = bool end @@ -323,6 +302,7 @@ module Net # :nodoc: @read_timeout = sec end + # # WARNING: This method causes serious security holes. # Use this method for only debugging. # @@ -332,9 +312,10 @@ module Net # :nodoc: # # example # smtp = Net::SMTP.new(addr, port) # smtp.set_debug_output $stderr - # smtp.start { + # smtp.start do |smtp| # .... - # } + # end + # def set_debug_output(arg) @debug_output = arg end @@ -343,16 +324,20 @@ module Net # :nodoc: # SMTP session control # + # # Creates a new Net::SMTP object and connects to the server. # # This method is equivalent to: # - # Net::SMTP.new(address,port).start(helo_domain,account,password,authtype) + # Net::SMTP.new(address, port).start(helo_domain, account, password, authtype) # - # # example - # Net::SMTP.start('your.smtp.server') { - # smtp.send_message msgstr, 'from@example.com', ['dest@example.com'] - # } + # === Example + # + # Net::SMTP.start('your.smtp.server') do |smtp| + # smtp.send_message msgstr, 'from@example.com', ['dest@example.com'] + # end + # + # === Block Usage # # If called with a block, the newly-opened Net::SMTP object is yielded # to the block, and automatically closed when the block finishes. If called @@ -360,16 +345,23 @@ module Net # :nodoc: # the caller, and it is the caller's responsibility to close it when # finished. # + # === Parameters + # # +address+ is the hostname or ip address of your smtp server. + # # +port+ is the port to connect to; it defaults to port 25. + # # +helo+ is the _HELO_ _domain_ provided by the client to the # server (see overview comments); it defaults to 'localhost.localdomain'. + # # The remaining arguments are used for SMTP authentication, if required # or desired. +user+ is the account name; +secret+ is your password # or other authentication token; and +authtype+ is the authentication # type, one of :plain, :login, or :cram_md5. See the discussion of # SMTP Authentication in the overview notes. # + # === Errors + # # This method may raise: # # * Net::SMTPAuthenticationError @@ -379,6 +371,7 @@ module Net # :nodoc: # * Net::SMTPUnknownError # * IOError # * TimeoutError + # def SMTP.start(address, port = nil, helo = 'localhost.localdomain', user = nil, secret = nil, authtype = nil, &block) # :yield: smtp @@ -390,21 +383,43 @@ module Net # :nodoc: @started end + # # Opens a TCP connection and starts the SMTP session. # + # === Parameters + # # +helo+ is the _HELO_ _domain_ that you'll dispatch mails from; see # the discussion in the overview notes. # + # If both of +user+ and +secret+ are given, SMTP authentication + # will be attempted using the AUTH command. +authtype+ specifies + # the type of authentication to attempt; it must be one of + # :login, :plain, and :cram_md5. See the notes on SMTP Authentication + # in the overview. + # + # === Block Usage + # # When this methods is called with a block, the newly-started SMTP # object is yielded to the block, and automatically closed after # the block call finishes. Otherwise, it is the caller's # responsibility to close the session when finished. # - # If both of +user+ and +secret+ are given, SMTP authentication - # will be attempted using the AUTH command. +authtype+ specifies - # the type of authentication to attempt; it must be one of - # :login, :plain, and :cram_md5. See the notes on SMTP Authentication - # in the overview. + # === Example + # + # This is very similar to the class method SMTP.start. + # + # require 'net/smtp' + # smtp = Net::SMTP.new('smtp.mail.server', 25) + # smtp.start(helo_domain, account, password, authtype) do |smtp| + # smtp.send_message msgstr, 'from@example.com', ['dest@example.com'] + # end + # + # The primary use of this method (as opposed to SMTP.start) + # is probably to set debugging (#set_debug_output) or ESMTP + # (#esmtp=), which must be done before the session is + # started. + # + # === Errors # # If session has already been started, an IOError will be raised. # @@ -417,8 +432,9 @@ module Net # :nodoc: # * Net::SMTPUnknownError # * IOError # * TimeoutError + # def start(helo = 'localhost.localdomain', - user = nil, secret = nil, authtype = nil) #:yield: smtp + user = nil, secret = nil, authtype = nil) # :yield: smtp if block_given? begin do_start(helo, user, secret, authtype) @@ -524,21 +540,26 @@ module Net # :nodoc: public + # # Sends +msgstr+ as a message. Single CR ("\r") and LF ("\n") found # in the +msgstr+, are converted into the CR LF pair. You cannot send a # binary message with this method. +msgstr+ should include both # the message headers and body. # # +from_addr+ is a String representing the source mail address. + # # +to_addr+ is a String or Strings or Array of Strings, representing # the destination mail address or addresses. # - # # example - # Net::SMTP.start('smtp.example.com') {|smtp| + # === Example + # + # Net::SMTP.start('smtp.example.com') do |smtp| # smtp.send_message msgstr, # 'from@example.com', # ['dest@example.com', 'dest2@example.com'] - # } + # end + # + # === Errors # # This method may raise: # @@ -548,6 +569,7 @@ module Net # :nodoc: # * Net::SMTPUnknownError # * IOError # * TimeoutError + # def send_message(msgstr, from_addr, *to_addrs) send0(from_addr, to_addrs.flatten) { @socket.write_message msgstr @@ -557,33 +579,40 @@ module Net # :nodoc: alias send_mail send_message alias sendmail send_message # obsolete + # # Opens a message writer stream and gives it to the block. # The 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. + # 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") is found in the message, # it is converted to the CR LF pair. You cannot send a binary # message with this method. # + # === Parameters + # # +from_addr+ is a String representing the source mail address. + # # +to_addr+ is a String or Strings or Array of Strings, representing # the destination mail address or addresses. # - # # example - # Net::SMTP.start('smtp.example.com', 25) {|smtp| - # smtp.open_message_stream('from@example.com', ['dest@example.com']) {|f| + # === Example + # + # Net::SMTP.start('smtp.example.com', 25) do |smtp| + # smtp.open_message_stream('from@example.com', ['dest@example.com']) do |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.' - # } - # } + # end + # end + # + # === Errors # # This method may raise: # @@ -593,7 +622,8 @@ module Net # :nodoc: # * Net::SMTPUnknownError # * IOError # * TimeoutError - def open_message_stream(from_addr, *to_addrs, &block) #:yield: stream + # + def open_message_stream(from_addr, *to_addrs, &block) # :yield: stream send0(from_addr, to_addrs.flatten) { @socket.write_message_by_block(&block) } -- cgit v1.2.3