首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Net::SMTP

Parent:Net::Protocol

What is This Library?

此库提供了通过SMTP(简单邮件传输协议)发送Internet邮件的功能。有关SMTP本身的详细信息,请参阅RFC2821。

What is This Library NOT?

这个库不提供编写网络邮件的功能。你必须自己创建它们。如果您想要更好的邮件支持,请尝试RubyMail或TMail或在RubyGems.orgRuby工具箱中搜索替代方案。

FYI:Internet邮件的官方文档是:RFC2822。

Examples

Sending Messages

在发送消息之前,您必须打开与SMTP服务器的连接。第一个参数是您的SMTP服务器的地址,第二个参数是端口号。使用::开始一个块是最简单的方法。这样,在执行该块后,SMTP连接会自动关闭。

代码语言:javascript
复制
require 'net/smtp'
Net::SMTP.start('your.smtp.server', 25) do |smtp|
  # Use the SMTP object smtp only in this block.
end

用你的SMTP服务器替换'your.smtp.server'。通常您的系统管理员或互联网提供商为您提供服务器。

然后你可以发送消息。

代码语言:javascript
复制
msgstr = <<END_OF_MESSAGE
From: Your Name <your@mail.address>
To: Destination Address <someone@example.com>
Subject: test message
Date: Sat, 23 Jun 2001 16:26:43 +0900
Message-Id: <unique.message.id.string@example.com>

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_address@example.com'
end

Closing the Session

您必须在发送消息后通过调用finish方法关闭SMTP会话:

代码语言:javascript
复制
# using SMTP#finish
smtp = Net::SMTP.start('your.smtp.server', 25)
smtp.send_message msgstr, 'from@address', 'to@address'
smtp.finish

您还可以使用:: start / SMTP#start的块形式。这会自动关闭SMTP会话:

代码语言:javascript
复制
# using block form of SMTP.start
Net::SMTP.start('your.smtp.server', 25) do |smtp|
  smtp.send_message msgstr, 'from@address', 'to@address'
end

我强烈推荐这个方案。这种形式更简单,更健壮。

HELO domain

在几乎所有情况下,您必须提供第三个参数:: start / SMTP#start。这是您所在的域名(主机发送邮件)。它被称为“HELO域”。SMTP服务器将通过检查HELO域来判断它是否应发送或拒绝SMTP会话。

代码语言:javascript
复制
Net::SMTP.start('your.smtp.server', 25,
                'mail.from.domain') { |smtp| ... }

SMTP Authentication

Net :: SMTP类支持三种认证方案; PLAIN,LOGIN和CRAM MD5。(SMTP验证:RFC2554)要使用SMTP验证,请将额外参数传递给:: start / SMTP#start。

代码语言:javascript
复制
# 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)

常量

CRAM_BUFSIZE DEFAULT_AUTH_TYPE

认证

IMASK OMASK Revision

Attributes

addressR

要连接到的SMTP服务器的地址。

esmtpRW

设置是否使用ESMTP。这应该在调用开始之前完成。请注意,如果在ESMTP模式下调用启动,并且由于ProtocolError导致连接失败,则SMTP对象将自动切换到纯SMTP模式并重试(但反之亦然)。

esmtp?RW

设置是否使用ESMTP。这应该在调用开始之前完成。请注意,如果在ESMTP模式下调用启动,并且由于ProtocolError导致连接失败,则SMTP对象将自动切换到纯SMTP模式并重试(但反之亦然)。

open_timeoutRW

秒等待尝试打开连接。如果在此时间内无法打开连接,则会引发Net :: OpenTimeout。默认值是30秒。

portR

要连接的SMTP服务器的端口号。

read_timeoutR

秒读等待一个块(通过一次读取(2)调用)。如果read(2)调用在此时间内未完成,则会引发Net :: ReadTimeout。默认值是60秒。

Public Class Methods

default_port() Show source

默认的SMTP端口号,25。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 174
def SMTP.default_port
  25
end

default_ssl_context()显示源文件

代码语言:javascript
复制
# File lib/net/smtp.rb, line 192
def SMTP.default_ssl_context
  OpenSSL::SSL::SSLContext.new
end

default_ssl_port()

别名为:default_tls_port

default_submission_port() Show source

默认邮件提交端口号,587。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 179
def SMTP.default_submission_port
  587
end

default_tls_port() Show source

默认的SMTPS端口号,465。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 184
def SMTP.default_tls_port
  465
end

另外别名为:default_ssl_port

new(address, port = nil) Show source

创建一个新的Net :: SMTP对象。

address是您的SMTP服务器的主机名或IP地址。port是连接的端口; 它默认为端口25。

此方法不会打开TCP连接。如果你想一次做所有事情,你可以使用:: start而不是:: new。否则,请使用#start追踪:: new。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 207
def initialize(address, port = nil)
  @address = address
  @port = (port || SMTP.default_port)
  @esmtp = true
  @capabilities = nil
  @socket = nil
  @started = false
  @open_timeout = 30
  @read_timeout = 60
  @error_occurred = false
  @debug_output = nil
  @tls = false
  @starttls = false
  @ssl_context = nil
end

start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... } Show source

创建一个新的Net :: SMTP对象并连接到服务器。

这种方法相当于:

代码语言:javascript
复制
Net::SMTP.new(address, port).start(helo_domain, account, password, authtype)

Example

代码语言:javascript
复制
Net::SMTP.start('your.smtp.server') do |smtp|
  smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
end

Block Usage

如果使用块调用,则新打开的Net :: SMTP对象被赋予块,并在块完成时自动关闭。如果在没有阻止的情况下调用,则新打开的Net :: SMTP对象将返回给调用者,并且调用者有责任在完成时关闭它。

Parameters

address 是您的smtp服务器的主机名或IP地址。

port是连接的端口; 它默认为端口25。

helo是客户端提供给服务器的HELO (请参阅概述注释); 它默认为'localhost'。

如果需要或需要,其余参数用于SMTP验证。user是帐户名称; secret是您的密码或其他身份验证令牌; 并且authtype是身份验证类型,其中包括:plain,:login或:cram_md5。请参阅概述说明中有关SMTP身份验证的讨论。

Errors

这种方法可能会引起:

  • Net::SMTPAuthenticationError
  • Net::SMTPServerBusy
  • Net::SMTPSyntaxError
  • Net::SMTPFatalError
  • Net::SMTPUnknownError
  • Net::OpenTimeout
  • Net::ReadTimeout
  • IOError
代码语言:javascript
复制
# File lib/net/smtp.rb, line 451
def SMTP.start(address, port = nil, helo = 'localhost',
               user = nil, secret = nil, authtype = nil,
               &block)   # :yield: smtp
  new(address, port).start(helo, user, secret, authtype, &block)
end

公共实例方法

auth_cram_md5(user, secret) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 750
def auth_cram_md5(user, secret)
  check_auth_args user, secret
  res = critical {
    res0 = get_response('AUTH CRAM-MD5')
    check_auth_continue res0
    crammed = cram_md5_response(secret, res0.cram_md5_challenge)
    get_response(base64_encode("#{user} #{crammed}"))
  }
  check_auth_response res
  res
end

auth_login(user, secret) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 739
def auth_login(user, secret)
  check_auth_args user, secret
  res = critical {
    check_auth_continue get_response('AUTH LOGIN')
    check_auth_continue get_response(base64_encode(user))
    get_response(base64_encode(secret))
  }
  check_auth_response res
  res
end

auth_plain(user, secret) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 730
def auth_plain(user, secret)
  check_auth_args user, secret
  res = critical {
    get_response('AUTH PLAIN ' + base64_encode("\0#{user}\0#{secret}"))
  }
  check_auth_response res
  res
end

authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 724
def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)
  check_auth_method authtype
  check_auth_args user, secret
  send auth_method(authtype), user, secret
end

capable_auth_types() Show source

返回此服务器上支持的身份验证方法 在打开SMTP会话之前,您无法获得有效的值。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 279
def capable_auth_types
  return [] unless @capabilities
  return [] unless @capabilities['AUTH']
  @capabilities['AUTH']
end

capable_cram_md5_auth?() Show source

如果服务器通告AUTH CRAM-MD5,则为true。在打开SMTP会话之前,您无法获得有效的值。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 266
def capable_cram_md5_auth?
  auth_capable?('CRAM-MD5')
end

capable_login_auth?() Show source

如果服务器通告AUTH LOGIN,则为true。在打开SMTP会话之前,您无法获得有效的值。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 260
def capable_login_auth?
  auth_capable?('LOGIN')
end

capable_plain_auth?() Show source

如果服务器通告AUTH PLAIN,则为true。在打开SMTP会话之前,您无法获得有效的值。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 254
def capable_plain_auth?
  auth_capable?('PLAIN')
end

capable_starttls?() Show source

如果服务器宣传STARTTLS,则为true。在打开SMTP会话之前,您无法获得有效的值。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 242
def capable_starttls?
  capable?('STARTTLS')
end

data(msgstr = nil) { |stream| ... } Show source

此方法发送消息。如果msgstr给出,则将其作为消息发送。如果给出块,则产生消息编写器流。您必须在该块关闭前写入消息。

代码语言:javascript
复制
# Example 1 (by string)
smtp.data("From: john@example.com
To: betty@example.com
Subject: I found a bug

Check vm.c:58879.
")

# Example 2 (by block)
smtp.data {|f|
  f.puts "From: john@example.com"
  f.puts "To: betty@example.com"
  f.puts "Subject: I found a bug"
  f.puts ""
  f.puts "Check vm.c:58879."
}
代码语言:javascript
复制
# File lib/net/smtp.rb, line 890
def data(msgstr = nil, &block)   #:yield: stream
  if msgstr and block
    raise ArgumentError, "message and block are exclusive"
  end
  unless msgstr or block
    raise ArgumentError, "message or block is required"
  end
  res = critical {
    check_continue get_response('DATA')
    socket_sync_bak = @socket.io.sync
    begin
      @socket.io.sync = false
      if msgstr
        @socket.write_message msgstr
      else
        @socket.write_message_by_block(&block)
      end
    ensure
      @socket.io.flush
      @socket.io.sync = socket_sync_bak
    end
    recv_response()
  }
  check_response res
  res
end

debug_output=(arg) Show source

警告:此方法会导致严重的安全漏洞。仅使用此方法进行调试。

设置输出流以进行调试日志记录。你必须在开始之前调用它。

代码语言:javascript
复制
# example
smtp = Net::SMTP.new(addr, port)
smtp.set_debug_output $stderr
smtp.start do |smtp|
  ....
end
代码语言:javascript
复制
# File lib/net/smtp.rb, line 392
def debug_output=(arg)
  @debug_output = arg
end

Also aliased as: set_debug_output

disable_ssl()

Alias for: disable_tls

disable_starttls() Show source

禁用此对象的SMTP / TLS(STARTTLS)。必须在建立连接之前调用才能起作用。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 350
def disable_starttls
  @starttls = false
  @ssl_context = nil
end

disable_tls() Show source

禁用此对象的SMTP / TLS。必须在建立连接之前调用才能起作用。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 306
def disable_tls
  @tls = false
  @ssl_context = nil
end

Also aliased as: disable_ssl

ehlo(domain) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 828
def ehlo(domain)
  getok("EHLO #{domain}")
end

enable_ssl(context = SMTP.default_ssl_context)

Alias for: enable_tls

enable_starttls(context = SMTP.default_ssl_context) Show source

为此对象启用SMTP / TLS(STARTTLS)。context是一个OpenSSL :: SSL :: SSLContext对象。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 332
def enable_starttls(context = SMTP.default_ssl_context)
  raise 'openssl library not installed' unless defined?(OpenSSL)
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
  @starttls = :always
  @ssl_context = context
end

enable_starttls_auto(context = SMTP.default_ssl_context) Show source

如果服务器接受,则为此对象启用SMTP / TLS(STARTTLS)。context是一个OpenSSL :: SSL :: SSLContext对象。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 341
def enable_starttls_auto(context = SMTP.default_ssl_context)
  raise 'openssl library not installed' unless defined?(OpenSSL)
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
  @starttls = :auto
  @ssl_context = context
end

enable_tls(context = SMTP.default_ssl_context) Show source

为此对象启用SMTP / TLS(SMTPS:通过直接TLS连接的SMTP)。必须在建立连接之前调用才能起作用。context是一个OpenSSL :: SSL :: SSLContext对象。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 295
def enable_tls(context = SMTP.default_ssl_context)
  raise 'openssl library not installed' unless defined?(OpenSSL)
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls
  @tls = true
  @ssl_context = context
end

Also aliased as: enable_ssl

finish() Show source

完成SMTP会话并关闭TCP连接。如果未启动,则引发IOError。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 530
def finish
  raise IOError, 'not yet started' unless started?
  do_finish
end

helo(domain) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 824
def helo(domain)
  getok("HELO #{domain}")
end

inspect() Show source

提供人类可读的类状态的字符串化。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 224
def inspect
  "#<#{self.class} #{@address}:#{@port} started=#{@started}>"
end

mailfrom(from_addr) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 832
def mailfrom(from_addr)
  if $SAFE > 0
    raise SecurityError, 'tainted from_addr' if from_addr.tainted?
  end
  getok("MAIL FROM:<#{from_addr}>")
end

open_message_stream(from_addr, *to_addrs) { |stream| ... } Show source

打开消息编写器流并将其提供给该块。该流只在该块中有效,并具有以下方法:

puts(str = '')

outputs STR and CR LF.

print(str)

outputs STR.

printf(fmt, *args)

outputs sprintf(fmt,*args).

write(str)

输出STR并返回写入字节的长度。

<<(str)

输出STR并返回自我。

如果在消息中找到单个CR(“r”)或LF(“n”),它将转换为CR LF对。您无法使用此方法发送二进制消息。

参数

from_addr 是表示源邮件地址的字符串。

to_addr 是一个字符串或字符串或字符串数​​组,表示目标邮件地址或地址。

Example

代码语言:javascript
复制
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

这种方法可能会引起:

  • Net::SMTPServerBusy
  • Net::SMTPSyntaxError
  • Net::SMTPFatalError
  • Net::SMTPUnknownError
  • Net::ReadTimeout
  • IOError
代码语言:javascript
复制
# File lib/net/smtp.rb, line 708
def open_message_stream(from_addr, *to_addrs, &block)   # :yield: stream
  raise IOError, 'closed session' unless @socket
  mailfrom from_addr
  rcptto_list(to_addrs) {data(&block)}
end

还有别名:ready

quit() Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 917
def quit
  getok('QUIT')
end

rcptto(to_addr) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 860
def rcptto(to_addr)
  if $SAFE > 0
    raise SecurityError, 'tainted to_addr' if to_addr.tainted?
  end
  getok("RCPT TO:<#{to_addr}>")
end

rcptto_list(to_addrs) { || ... } Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 839
def rcptto_list(to_addrs)
  raise ArgumentError, 'mail destination not given' if to_addrs.empty?
  ok_users = []
  unknown_users = []
  to_addrs.flatten.each do |addr|
    begin
      rcptto addr
    rescue SMTPAuthenticationError
      unknown_users << addr.dump
    else
      ok_users << addr
    end
  end
  raise ArgumentError, 'mail destination not given' if ok_users.empty?
  ret = yield
  unless unknown_users.empty?
    raise SMTPAuthenticationError, "failed to deliver for #{unknown_users.join(', ')}"
  end
  ret
end

read_timeout=(sec) Show source

设置要等到读取(2)调用超时的秒数。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 373
def read_timeout=(sec)
  @socket.read_timeout = sec if @socket
  @read_timeout = sec
end

ready(from_addr, *to_addrs)

别名为:open_message_stream

rset() Show source

中止当前的邮件交易

代码语言:javascript
复制
# File lib/net/smtp.rb, line 816
def rset
  getok('RSET')
end

send_mail(msgstr, from_addr, *to_addrs)

别名为:send_message

send_message(msgstr, from_addr, *to_addrs) Show source

发送msgstr作为消息。找到的单个CR(“r”)和LF(“n”)msgstr被转换为CR LF对。您无法使用此方法发送二进制消息。msgstr应该包含消息标题和正文。

from_addr 是表示源邮件地址的字符串。

to_addr 是一个字符串或字符串或字符串数​​组,表示目标邮件地址或地址。

Example

代码语言:javascript
复制
Net::SMTP.start('smtp.example.com') do |smtp|
  smtp.send_message msgstr,
                    'from@example.com',
                    ['dest@example.com', 'dest2@example.com']
end

Errors

这种方法可能会引起:

  • Net::SMTPServerBusy
  • Net::SMTPSyntaxError
  • Net::SMTPFatalError
  • Net::SMTPUnknownError
  • Net::ReadTimeout
  • IOError
代码语言:javascript
复制
# File lib/net/smtp.rb, line 655
def send_message(msgstr, from_addr, *to_addrs)
  raise IOError, 'closed session' unless @socket
  mailfrom from_addr
  rcptto_list(to_addrs) {data msgstr}
end

另外别名为:send_mail,sendmail

sendmail(msgstr, from_addr, *to_addrs)

别名为:send_message

set_debug_output(ARG)

别名为:debug_output =

ssl?()

别名为:tls?

start(helo ='localhost',user = nil,secret = nil,authtype = nil){| smtp | ...}显示源文件

打开TCP连接并启动SMTP会话。

Parameters

helo是您将派遣邮件的HELO 域名 ; 请参阅概述说明中的讨论。

如果这两个usersecret给出,SMTP身份验证将使用AUTH命令进行尝试。authtype指定要尝试的认证类型; 它必须是以下之一:login,:plain和:cram_md5。请参阅概述中有关SMTP身份验证的注意事项。

Block Usage

当使用块调用此方法时,新启动的SMTP对象被赋予块,并在块调用完成后自动关闭。否则,完成后关闭会话是主叫方的责任。

Example

这与类方法:: start非常相似。

代码语言:javascript
复制
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

此方法(与:: start相反)的主要用途可能是设置调试(#set_debug_output)或ESMTP(#esmtp =),这必须在会话启动之前完成。

Errors

如果会话已经启动,则会引发IOError。

这种方法可能会引起:

  • Net::SMTPAuthenticationError
  • Net::SMTPServerBusy
  • Net::SMTPSyntaxError
  • Net::SMTPFatalError
  • Net::SMTPUnknownError
  • Net::OpenTimeout
  • Net::ReadTimeout
  • IOError
代码语言:javascript
复制
# File lib/net/smtp.rb, line 513
def start(helo = 'localhost',
          user = nil, secret = nil, authtype = nil)   # :yield: smtp
  if block_given?
    begin
      do_start helo, user, secret, authtype
      return yield(self)
    ensure
      do_finish
    end
  else
    do_start helo, user, secret, authtype
    return self
  end
end

started?() Show source

true 如果SMTP会话已启动。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 458
def started?
  @started
end

starttls() Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 820
def starttls
  getok('STARTTLS')
end

starttls?() Show source

如果此对象使用STARTTLS,则返回真值。如果这个对象总是使用STARTTLS,则返回:always。如果此对象在服务器支持TLS时使用STARTTLS,则返回:auto。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 316
def starttls?
  @starttls
end

starttls_always?() Show source

如果此对象使用STARTTLS,则为true。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 321
def starttls_always?
  @starttls == :always
end

starttls_auto?() Show source

如果此对象在服务器通告STARTTLS时使用STARTTLS,则为true。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 326
def starttls_auto?
  @starttls == :auto
end

tls?() Show source

如果此对象使用SMTP / TLS(SMTPS),则返回true。

代码语言:javascript
复制
# File lib/net/smtp.rb, line 286
def tls?
  @tls
end

Also aliased as: ssl?

私有实例方法

auth_capable?(type) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 270
def auth_capable?(type)
  return nil unless @capabilities
  return false unless @capabilities['AUTH']
  @capabilities['AUTH'].include?(type)
end

auth_method(type) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 770
def auth_method(type)
  "auth_#{type.to_s.downcase}".intern
end

base64_encode(str) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 783
def base64_encode(str)
  # expects "str" may not become too long
  [str].pack('m0')
end

capable?(key) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 246
def capable?(key)
  return nil unless @capabilities
  @capabilities[key] ? true : false
end

check_auth_args(用户,秘密,authtype = DEFAULT_AUTH_TYPE)显示源

代码语言:javascript
复制
# File lib/net/smtp.rb, line 774
def check_auth_args(user, secret, authtype = DEFAULT_AUTH_TYPE)
  unless user
    raise ArgumentError, 'SMTP-AUTH requested but missing user name'
  end
  unless secret
    raise ArgumentError, 'SMTP-AUTH requested but missing secret phrase'
  end
end

check_auth_continue(res) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 984
def check_auth_continue(res)
  unless res.continue?
    raise res.exception_class, res.message
  end
end

check_auth_method(type) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 764
def check_auth_method(type)
  unless respond_to?(auth_method(type), true)
    raise ArgumentError, "wrong authentication type #{type}"
  end
end

check_auth_response(res) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 978
def check_auth_response(res)
  unless res.success?
    raise SMTPAuthenticationError, res.message
  end
end

check_continue(res) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 972
def check_continue(res)
  unless res.continue?
    raise SMTPUnknownError, "could not get 3xx (#{res.status}: #{res.string})"
  end
end

check_response(res) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 966
def check_response(res)
  unless res.success?
    raise res.exception_class, res.message
  end
end

cram_md5_response(secret, challenge) Show source

CRAM-MD5: RFC2195

代码语言:javascript
复制
# File lib/net/smtp.rb, line 792
def cram_md5_response(secret, challenge)
  tmp = Digest::MD5.digest(cram_secret(secret, IMASK) + challenge)
  Digest::MD5.hexdigest(cram_secret(secret, OMASK) + tmp)
end

cram_secret(secret, mask) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 799
def cram_secret(secret, mask)
  secret = Digest::MD5.digest(secret) if secret.size > CRAM_BUFSIZE
  buf = secret.ljust(CRAM_BUFSIZE, "\0")
  0.upto(buf.size - 1) do |i|
    buf[i] = (buf[i].ord ^ mask).chr
  end
  buf
end

critical() { || ... } Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 956
def critical
  return Response.parse('200 dummy reply code') if @error_occurred
  begin
    return yield()
  rescue Exception
    @error_occurred = true
    raise
  end
end

do_finish() Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 610
def do_finish
  quit if @socket and not @socket.closed? and not @error_occurred
ensure
  @started = false
  @error_occurred = false
  @socket.close if @socket
  @socket = nil
end

do_helo(helo_domain) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 598
def do_helo(helo_domain)
  res = @esmtp ? ehlo(helo_domain) : helo(helo_domain)
  @capabilities = res.capabilities
rescue SMTPError
  if @esmtp
    @esmtp = false
    @error_occurred = false
    retry
  end
  raise
end

do_start(helo_domain, user, secret, authtype) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 541
def do_start(helo_domain, user, secret, authtype)
  raise IOError, 'SMTP session already started' if @started
  if user or secret
    check_auth_method(authtype || DEFAULT_AUTH_TYPE)
    check_auth_args user, secret
  end
  s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do
    tcp_socket(@address, @port)
  end
  logging "Connection opened: #{@address}:#{@port}"
  @socket = new_internet_message_io(tls? ? tlsconnect(s) : s)
  check_response critical { recv_response() }
  do_helo helo_domain
  if starttls_always? or (capable_starttls? and starttls_auto?)
    unless capable_starttls?
      raise SMTPUnsupportedCommand,
          "STARTTLS is not supported on this server"
    end
    starttls
    @socket = new_internet_message_io(tlsconnect(s))
    # helo response may be different after STARTTLS
    do_helo helo_domain
  end
  authenticate user, secret, (authtype || DEFAULT_AUTH_TYPE) if user
  @started = true
ensure
  unless @started
    # authentication failed, cancel connection.
    s.close if s
    @socket = nil
  end
end

get_response(reqline) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 940
def get_response(reqline)
  validate_line reqline
  @socket.writeline reqline
  recv_response()
end

getok(reqline) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 930
def getok(reqline)
  validate_line reqline
  res = critical {
    @socket.writeline reqline
    recv_response()
  }
  check_response res
  res
end

logging(msg) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 1069
def logging(msg)
  @debug_output << msg + "\n" if @debug_output
end

new_internet_message_io(s) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 593
def new_internet_message_io(s)
  InternetMessageIO.new(s, read_timeout: @read_timeout,
                        debug_output: @debug_output)
end

recv_response() Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 946
def recv_response
  buf = ''
  while true
    line = @socket.readline
    buf << line << "\n"
    break unless line[3,1] == '-'   # "210-PIPELINING"
  end
  Response.parse(buf)
end

ssl_socket(socket, context) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 574
def ssl_socket(socket, context)
  OpenSSL::SSL::SSLSocket.new socket, context
end

tcp_socket(address, port) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 537
def tcp_socket(address, port)
  TCPSocket.open address, port
end

tlsconnect(s) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 578
def tlsconnect(s)
  verified = false
  s = ssl_socket(s, @ssl_context)
  logging "TLS connection started"
  s.sync_close = true
  ssl_socket_connect(s, @open_timeout)
  if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
    s.post_connection_check(@address)
  end
  verified = true
  s
ensure
  s.close unless verified
end

validate_line(line) Show source

代码语言:javascript
复制
# File lib/net/smtp.rb, line 923
def validate_line(line)
  # A bare CR or LF is not allowed in RFC5321.
  if /[\r\n]/ =~ line
    raise ArgumentError, "A line must not contain CR or LF"
  end
end

扫码关注腾讯云开发者

领取腾讯云代金券