Spec-Zone.ru › Ruby 3

класс Net::SMTP

Родитель:
Net::Protocol

Что представляет собой эта библиотека?

Эта библиотека предоставляет возможность отправлять электронную почту по протоколу SMTP, Simple Mail Transfer Protocol. Подробные сведения о самом SMTP см. в [RFC2821] (www.ietf.org/rfc/rfc2821.txt).

Что эта библиотека НЕ делает?

Эта библиотека НЕ предоставляет функций для составления сообщений электронной почты. Вы должны создавать их самостоятельно. Если вам нужна лучшая поддержка почты, попробуйте RubyMail или TMail, или найдите альтернативы на RubyGems.org или The Ruby Toolbox.

Для справки: официальная документация по электронной почте: [RFC2822] (www.ietf.org/rfc/rfc2822.txt).

Примеры

Отправка сообщений

Перед отправкой сообщений необходимо установить соединение с сервером SMTP. Первым аргументом является адрес вашего сервера SMTP, а вторым — номер порта. Использование SMTP.start с блоком — самый простой способ сделать это. Таким образом, подключение к SMTP автоматически закрывается после выполнения блока.

require 'net/smtp'
Net::SMTP.start('your.smtp.server', 25) do |smtp|
  # Use the SMTP object smtp only in this block.
end

Замените 'your.smtp.server' на ваш сервер SMTP. Обычно ваш системный администратор или провайдер интернет-услуг предоставляет вам сервер.

Затем вы можете отправлять сообщения.

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

Закрытие сеанса

ОБЯЗАТЕЛЬНО закройте сеанс SMTP после отправки сообщений, вызвав метод finish:

# using SMTP#finish
smtp = Net::SMTP.start('your.smtp.server', 25)
smtp.send_message msgstr, 'from@address', 'to@address'
smtp.finish

Вы также можете использовать блочный формат SMTP.start/SMTP#start. Это автоматически закроет сеанс SMTP:

# 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 домен

Практически во всех случаях вам необходимо предоставить третий аргумент для SMTP.start/SMTP#start. Это имя домена, на котором вы находитесь (хост для отправки почты). Это «HELO домен». Сервер SMTP будет судить, следует ли ему отправлять или отклонять сеанс SMTP, анализируя HELO домен.

Net::SMTP.start('your.smtp.server', 25
                helo: 'mail.from.domain') { |smtp| ... }

SMTP Аутентификация

Класс Net::SMTP поддерживает три схемы аутентификации: PLAIN, LOGIN и CRAM MD5. (SMTP Аутентификация: [RFC2554]) Для использования SMTP аутентификации передайте дополнительные аргументы в SMTP.start/SMTP#start.

# PLAIN
Net::SMTP.start('your.smtp.server', 25
                user: 'Your Account', secret: 'Your Password', authtype: :plain)
# LOGIN
Net::SMTP.start('your.smtp.server', 25
                user: 'Your Account', secret: 'Your Password', authtype: :login)

# CRAM MD5
Net::SMTP.start('your.smtp.server', 25
                user: 'Your Account', secret: 'Your Password', authtype: :cram_md5)

Константы

CRAM_BUFSIZE
DEFAULT_AUTH_TYPE

Аутентификация

IMASK
OMASK
Revision
VERSION

Атрибуты

address[R]

Адрес сервера SMTP для подключения.

esmtp[RW]

Set использовать ESMTP или нет. Это необходимо сделать до вызова start. Обратите внимание, что если start вызывается в режиме ESMTP, и подключение прерывается из-за ProtocolError, объект SMTP автоматически переключится на обычный режим SMTP и повторит попытку (но не наоборот).

esmtp?[RW]

Set использовать ESMTP или нет. Это необходимо сделать до вызова start. Обратите внимание, что если start вызывается в режиме ESMTP, и подключение прерывается из-за ProtocolError, объект SMTP автоматически переключится на обычный режим SMTP и повторит попытку (но не наоборот).

open_timeout[RW]

Секунды ожидания при попытке открытия подключения. Если подключение не может быть открыто в течение этого времени, генерируется исключение Net::OpenTimeout. Значение по умолчанию — 30 секунд.

port[R]

Порт сервера SMTP для подключения.

read_timeout[R]

Секунды ожидания при чтении одного блока (одним вызовом read(2)). Если вызов read(2) не завершится в течение этого времени, генерируется исключение Net::ReadTimeout. Значение по умолчанию — 60 секунд.

Методы публичного класса

default_port() Показать исходный код
# File lib/net/smtp.rb, line 176
def SMTP.default_port
  25
end

Порт по умолчанию сервера SMTP, 25.

default_ssl_context(verify_peer=true) Показать исходный код
# File lib/net/smtp.rb, line 194
def SMTP.default_ssl_context(verify_peer=true)
  context = OpenSSL::SSL::SSLContext.new
  context.verify_mode = verify_peer ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
  store = OpenSSL::X509::Store.new
  store.set_default_paths
  context.cert_store = store
  context
end
default_ssl_port()
Псевдоним для: default_tls_port
default_submission_port() Показать исходный код
# File lib/net/smtp.rb, line 181
def SMTP.default_submission_port
  587
end

Порт по умолчанию для отправки почты, 587.

default_tls_port() Показать исходный код
# File lib/net/smtp.rb, line 186
def SMTP.default_tls_port
  465
end

Порт по умолчанию SMTPS, 465.

Также псевдоним для: default_ssl_port
new(address, port = nil) Показать исходный код
# File lib/net/smtp.rb, line 214
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 = :auto
  @ssl_context_tls = nil
  @ssl_context_starttls = nil
end

Создает новый объект Net::SMTP.

address — имя хоста или IP-адрес вашего сервера SMTP. port — порт для подключения; по умолчанию используется порт 25.

Этот метод не открывает TCP-соединение. Вы можете использовать SMTP.start вместо SMTP.new, если хотите выполнить все сразу. В противном случае, следуйте SMTP.new с SMTP#start.

start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... } Показать исходный код
start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
# File lib/net/smtp.rb, line 466
def SMTP.start(address, port = nil, *args, helo: nil,
               user: nil, secret: nil, password: nil, authtype: nil,
               tls_verify: true, tls_hostname: nil,
               &block)
  raise ArgumentError, "wrong number of arguments (given #{args.size + 2}, expected 1..6)" if args.size > 4
  helo ||= args[0] || 'localhost'
  user ||= args[1]
  secret ||= password || args[2]
  authtype ||= args[3]
  new(address, port).start(helo: helo, user: user, secret: secret, authtype: authtype, tls_verify: tls_verify, tls_hostname: tls_hostname, &block)
end

Создает новый объект Net::SMTP и подключается к серверу.

Этот метод эквивалентен:

Net::SMTP.new(address, port).start(helo: helo_domain, user: account, secret: password, authtype: authtype, tls_verify: flag, tls_hostname: hostname)

Пример

Net::SMTP.start('your.smtp.server') do |smtp|
  smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
end

Использование блока

Если вызывается с блоком, созданный объект Net::SMTP передается в блок, и автоматически закрывается по завершении блока. Если вызывается без блока, созданный объект Net::SMTP возвращается вызывающей стороне, и ответственность за его закрытие ложится на вызывающую сторону.

Параметры

address — имя хоста или IP-адрес вашего сервера SMTP.

port — порт для подключения; по умолчанию используется порт 25.

helo — домен HElo, предоставленный клиентом серверу (см. комментарии обзора); по умолчанию — 'localhost'.

Остальные аргументы используются для аутентификации SMTP, если требуется. user — имя пользователя; secret — ваш пароль или другой аутентификационный токен; а authtype — тип аутентификации, один из: :plain, :login или :cram_md5. См. обсуждение аутентификации SMTP в заметках обзора. Если tls_verify — true, проверяйте сертификат сервера. По умолчанию — true. Если имя хоста в сертификате сервера отличается от address, его можно указать с помощью tls_hostname.

Ошибки

Этот метод может вызывать следующие ошибки:

  • Net::SMTPAuthenticationError

  • Net::SMTPServerBusy

  • Net::SMTPSyntaxError

  • Net::SMTPFatalError

  • Net::SMTPUnknownError

  • Net::OpenTimeout

  • Net::ReadTimeout

  • IOError

Общедоступные методы экземпляров

auth_cram_md5(user, secret) Показать исходный код
# File lib/net/smtp.rb, line 791
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) Показать исходный код
# File lib/net/smtp.rb, line 780
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) Показать исходный код
# File lib/net/smtp.rb, line 771
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) Показать исходный код
# File lib/net/smtp.rb, line 765
def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)
  check_auth_method authtype
  check_auth_args user, secret
  public_send auth_method(authtype), user, secret
end
capable_auth_types() Показать исходный код
# File lib/net/smtp.rb, line 287
def capable_auth_types
  return [] unless @capabilities
  return [] unless @capabilities['AUTH']
  @capabilities['AUTH']
end

Возвращает поддерживаемые методы аутентификации на данном сервере. Вы не сможете получить корректное значение до открытия сессии SMTP.

capable_cram_md5_auth?() Показать исходный код
# File lib/net/smtp.rb, line 274
def capable_cram_md5_auth?
  auth_capable?('CRAM-MD5')
end

true, если сервер поддерживает AUTH CRAM-MD5. Вы не сможете получить корректное значение до открытия сессии SMTP.

capable_login_auth?() Показать исходный код
# File lib/net/smtp.rb, line 268
def capable_login_auth?
  auth_capable?('LOGIN')
end

true, если сервер поддерживает AUTH LOGIN. Вы не сможете получить корректное значение до открытия сессии SMTP.

capable_plain_auth?() Показать исходный код
# File lib/net/smtp.rb, line 262
def capable_plain_auth?
  auth_capable?('PLAIN')
end

true, если сервер поддерживает AUTH PLAIN. Вы не сможете получить корректное значение до открытия сессии SMTP.

capable_starttls?() Показать исходный код
# File lib/net/smtp.rb, line 250
def capable_starttls?
  capable?('STARTTLS')
end

true, если сервер поддерживает STARTTLS. Вы не сможете получить корректное значение до открытия сессии SMTP сессии.

data(msgstr = nil) { |stream| ... } Показать исходный код
# File lib/net/smtp.rb, line 925
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

Этот метод отправляет сообщение. Если msgstr указан, отправляет его как сообщение. Если задан блок, передает поток для записи сообщения. Вы должны записать сообщение перед закрытием блока.

# Example 1 (by string)
smtp.data(<<EndMessage)
From: john@example.com
To: betty@example.com
Subject: I found a bug

Check vm.c:58879.
EndMessage

# 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."
}
debug_output=(arg) Показать исходный код
# File lib/net/smtp.rb, line 400
def debug_output=(arg)
  @debug_output = arg
end

ПРЕДУПРЕЖДЕНИЕ: Этот метод может привести к серьезным уязвимостям безопасности. Используйте его только для отладки.

Устанавливает поток вывода для отладочной регистрации. Необходимо вызвать этот метод до вызова start.

# example
smtp = Net::SMTP.new(addr, port)
smtp.set_debug_output $stderr
smtp.start do |smtp|
  ....
end
Также алиасируется как: set_debug_output
disable_ssl()
Псевдоним для: disable_tls
disable_starttls() Показать исходный код
# File lib/net/smtp.rb, line 358
def disable_starttls
  @starttls = false
  @ssl_context_starttls = nil
end

Отключает SMTP/TLS (STARTTLS) для данного объекта. Необходимо вызвать этот метод до установления соединения, чтобы он подействовал.

disable_tls() Показать исходный код
# File lib/net/smtp.rb, line 314
def disable_tls
  @tls = false
  @ssl_context_tls = nil
end

Отключает SMTP/TLS для данного объекта. Необходимо вызвать этот метод до установления соединения, чтобы он подействовал.

Также алиасируется как: disable_ssl
ehlo(domain) Показать исходный код
# File lib/net/smtp.rb, line 869
def ehlo(domain)
  getok("EHLO #{domain}")
end
enable_ssl(context = nil)
Псевдоним для: enable_tls
enable_starttls(context = nil) Показать исходный код
# File lib/net/smtp.rb, line 340
def enable_starttls(context = nil)
  raise 'openssl library not installed' unless defined?(OpenSSL)
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
  @starttls = :always
  @ssl_context_starttls = context
end

Включает SMTP/TLS (STARTTLS) для данного объекта. context — объект OpenSSL::SSL::SSLContext.

enable_starttls_auto(context = nil) Показать исходный код
# File lib/net/smtp.rb, line 349
def enable_starttls_auto(context = nil)
  raise 'openssl library not installed' unless defined?(OpenSSL)
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
  @starttls = :auto
  @ssl_context_starttls = context
end

Включает SMTP/TLS (STARTTLS) для данного объекта, если сервер его поддерживает. context — объект OpenSSL::SSL::SSLContext.

enable_tls(context = nil) Показать исходный код
# File lib/net/smtp.rb, line 303
def enable_tls(context = nil)
  raise 'openssl library not installed' unless defined?(OpenSSL)
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls == :always
  @tls = true
  @ssl_context_tls = context
end

Включает SMTP/TLS (SMTPS: SMTP через прямое TLS-соединение) для данного объекта. Необходимо вызвать этот метод до установления соединения, чтобы он подействовал. context — объект OpenSSL::SSL::SSLContext.

Также алиасируется как: enable_ssl
finish() Показать исходный код
# File lib/net/smtp.rb, line 570
def finish
  raise IOError, 'not yet started' unless started?
  do_finish
end

Завершает сессию SMTP и закрывает TCP-соединение. Возбуждает исключение IOError, если сессия не начата.

helo(domain) Показать исходный код
# File lib/net/smtp.rb, line 865
def helo(domain)
  getok("HELO #{domain}")
end
inspect() Показать исходный код
# File lib/net/smtp.rb, line 232
def inspect
  "#<#{self.class} #{@address}:#{@port} started=#{@started}>"
end

Возвращает удобочитаемое строковое представление состояния класса.

mailfrom(from_addr) Показать исходный код
# File lib/net/smtp.rb, line 873
def mailfrom(from_addr)
  getok("MAIL FROM:<#{from_addr}>")
end
END_OF_DOCUMENT_MARKER
open_message_stream(from_addr, *to_addrs) { |stream| ... } Показать исходный код
# File lib/net/smtp.rb, line 749
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

Открывает поток для записи сообщения и передает его в блок. Поток действителен только внутри блока и имеет следующие методы:

puts(str = '')

выводит STR и CR LF.

print(str)

выводит STR.

printf(fmt, *args)

выводит sprintf(fmt,*args).

write(str)

выводит STR и возвращает длину записанных байтов.

<<(str)

выводит STR и возвращает self.

Если в сообщении встречается одиночный символ CR («r») или LF («n»), он преобразуется в пару CR LF. Вы не можете отправлять двоичные сообщения с помощью этого метода.

Параметры

from_addr — String, представляющий адрес исходной почты.

to_addr — String или строки или Array строк, представляющие адрес или адреса назначения почты.

Пример

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

Ошибки

Этот метод может вызвать:

  • Net::SMTPServerBusy

  • Net::SMTPSyntaxError

  • Net::SMTPFatalError

  • Net::SMTPUnknownError

  • Net::ReadTimeout

  • IOError

Также известен как: ready
quit() Показать исходный код
# File lib/net/smtp.rb, line 952
def quit
  getok('QUIT')
end
rcptto(to_addr) Показать исходный код
# File lib/net/smtp.rb, line 898
def rcptto(to_addr)
  getok("RCPT TO:<#{to_addr}>")
end
rcptto_list(to_addrs) { || ... } Показать исходный код
# File lib/net/smtp.rb, line 877
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) Показать исходный код
# File lib/net/smtp.rb, line 381
def read_timeout=(sec)
  @socket.read_timeout = sec if @socket
  @read_timeout = sec
end

Set количество секунд ожидания при таймауте вызова read(2).

ready(from_addr, *to_addrs)
Псевдоним для: open_message_stream
rset() Показать исходный код
# File lib/net/smtp.rb, line 857
def rset
  getok('RSET')
end

Прерывает текущую транзакцию отправки почты.

send_mail(msgstr, from_addr, *to_addrs)
Псевдоним для: send_message
send_message(msgstr, from_addr, *to_addrs) Показать исходный код
# File lib/net/smtp.rb, line 696
def send_message(msgstr, from_addr, *to_addrs)
  raise IOError, 'closed session' unless @socket
  mailfrom from_addr
  rcptto_list(to_addrs) {data msgstr}
end

Отправляет msgstr как сообщение. Одиночные CR («r») и LF («n»), найденные в msgstr, преобразуются в пару CR LF. С этим методом нельзя отправлять двоичные сообщения. msgstr должно включать как заголовки, так и тело сообщения.

from_addr — String, представляющий адрес исходной почты.

to_addr — String или строки или Array строк, представляющие адрес или адреса назначения почты.

Пример

Net::SMTP.start('smtp.example.com') do |smtp|
  smtp.send_message msgstr,
                    'from@example.com',
                    ['dest@example.com', 'dest2@example.com']
end

Ошибки

Этот метод может вызвать:

  • Net::SMTPServerBusy

  • Net::SMTPSyntaxError

  • Net::SMTPFatalError

  • Net::SMTPUnknownError

  • Net::ReadTimeout

  • IOError

Также известен как: 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, tls_verify: true, tls_hostname: nil) { |smtp| ... } Показать исходный код
start(helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
# File lib/net/smtp.rb, line 541
def start(*args, helo: nil,
          user: nil, secret: nil, password: nil, authtype: nil, tls_verify: true, tls_hostname: nil)
  raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..4)" if args.size > 4
  helo ||= args[0] || 'localhost'
  user ||= args[1]
  secret ||= password || args[2]
  authtype ||= args[3]
  if @tls && @ssl_context_tls.nil?
    @ssl_context_tls = SMTP.default_ssl_context(tls_verify)
  end
  if @starttls && @ssl_context_starttls.nil?
    @ssl_context_starttls = SMTP.default_ssl_context(tls_verify)
  end
  @tls_hostname = tls_hostname
  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

Открывает TCP-соединение и начинает сеанс SMTP.

Параметры

helo — домен HELO, с которого вы будете отправлять почту; см. обсуждение в заметках к обзору.

Если оба user и secret заданы, будет выполнена аутентификация SMTP с помощью команды AUTH. authtype определяет тип аутентификации; он должен быть одним из: login, plain, cram_md5. См. заметки об аутентификации SMTP в обзоре. Если tls_verify равно true, серверный сертификат будет проверен. По умолчанию — true. Если имя хоста в серверном сертификате отличается от address, оно может быть указано в tls_hostname.

Использование блока

Когда этот метод вызывается с блоком, новый объект SMTP передаётся в блок и автоматически закрывается после завершения вызова блока. В противном случае, ответственность за закрытие сеанса лежит на вызывающей стороне.

Пример

Это очень похоже на метод класса SMTP.start.

require 'net/smtp'
smtp = Net::SMTP.new('smtp.mail.server', 25)
smtp.start(helo: helo_domain, user: account, secret: password, authtype: authtype) do |smtp|
  smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
end

Основное использование этого метода (в отличие от SMTP.start) — вероятно, настройка отладки (set_debug_output) или ESMTP (esmtp=), которые должны быть выполнены до начала сеанса.

Ошибки

Если сеанс уже начат, будет выброшено исключение IOError.

Этот метод может вызвать:

  • Net::SMTPAuthenticationError

  • Net::SMTPServerBusy

  • Net::SMTPSyntaxError

  • Net::SMTPFatalError

  • Net::SMTPUnknownError

  • Net::OpenTimeout

  • Net::ReadTimeout

  • IOError

started?() Показать исходный код
# File lib/net/smtp.rb, line 479
def started?
  @started
end

Возвращает true, если сеанс SMTP запущен.

starttls() Показать исходный код
# File lib/net/smtp.rb, line 861
def starttls
  getok('STARTTLS')
end
END_OF_DOCUMENT_MARKER
starttls?() Показать исходный код
# File lib/net/smtp.rb, line 324
def starttls?
  @starttls
end

Возвращает логическое значение, если этот объект использует STARTTLS. Если этот объект всегда использует STARTTLS, возвращает :always. Если этот объект использует STARTTLS, когда сервер поддерживает TLS, возвращает :auto.

starttls_always?() Показать исходный код
# File lib/net/smtp.rb, line 329
def starttls_always?
  @starttls == :always
end

true, если этот объект использует STARTTLS.

starttls_auto?() Показать исходный код
# File lib/net/smtp.rb, line 334
def starttls_auto?
  @starttls == :auto
end

true, если этот объект использует STARTTLS, когда сервер объявляет STARTTLS.

tls?() Показать исходный код
# File lib/net/smtp.rb, line 294
def tls?
  @tls
end

true, если этот объект использует SMTP/TLS (SMTPS).

Также известен как: ssl?

Приватные методы экземпляра

auth_capable?(type) Показать исходный код
# File lib/net/smtp.rb, line 278
def auth_capable?(type)
  return nil unless @capabilities
  return false unless @capabilities['AUTH']
  @capabilities['AUTH'].include?(type)
end
auth_method(type) Показать исходный код
# File lib/net/smtp.rb, line 811
def auth_method(type)
  "auth_#{type.to_s.downcase}".intern
end
base64_encode(str) Показать исходный код
# File lib/net/smtp.rb, line 824
def base64_encode(str)
  # expects "str" may not become too long
  [str].pack('m0')
end
capable?(key) Показать исходный код
# File lib/net/smtp.rb, line 254
def capable?(key)
  return nil unless @capabilities
  @capabilities[key] ? true : false
end
check_auth_args(user, secret, authtype = DEFAULT_AUTH_TYPE) Показать исходный код
# File lib/net/smtp.rb, line 815
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) Показать исходный код
# File lib/net/smtp.rb, line 1019
def check_auth_continue(res)
  unless res.continue?
    raise res.exception_class, res.message
  end
end
check_auth_method(type) Показать исходный код
# File lib/net/smtp.rb, line 805
def check_auth_method(type)
  unless respond_to?(auth_method(type), true)
    raise ArgumentError, "wrong authentication type #{type}"
  end
end
check_auth_response(res) Показать исходный код
# File lib/net/smtp.rb, line 1013
def check_auth_response(res)
  unless res.success?
    raise SMTPAuthenticationError, res.message
  end
end
check_continue(res) Показать исходный код
# File lib/net/smtp.rb, line 1007
def check_continue(res)
  unless res.continue?
    raise SMTPUnknownError, "could not get 3xx (#{res.status}: #{res.string})"
  end
end
check_response(res) Показать исходный код
# File lib/net/smtp.rb, line 1001
def check_response(res)
  unless res.success?
    raise res.exception_class, res.message
  end
end
cram_md5_response(secret, challenge) Показать исходный код
# File lib/net/smtp.rb, line 833
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-MD5: [RFC2195]

cram_secret(secret, mask) Показать исходный код
# File lib/net/smtp.rb, line 840
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() { || ... } Показать исходный код
# File lib/net/smtp.rb, line 991
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() Показать исходный код
# File lib/net/smtp.rb, line 651
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) Показать исходный код
# File lib/net/smtp.rb, line 639
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) Показать исходный код
# File lib/net/smtp.rb, line 581
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, @ssl_context_tls) : s)
  check_response critical { recv_response() }
  do_helo helo_domain
  if ! tls? and (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, @ssl_context_starttls))
    # 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) Показать исходный код
# File lib/net/smtp.rb, line 975
def get_response(reqline)
  validate_line reqline
  @socket.writeline reqline
  recv_response()
end
getok(reqline) Показать исходный код
# File lib/net/smtp.rb, line 965
def getok(reqline)
  validate_line reqline
  res = critical {
    @socket.writeline reqline
    recv_response()
  }
  check_response res
  res
end
logging(msg) Показать исходный код
# File lib/net/smtp.rb, line 1104
def logging(msg)
  @debug_output << msg + "\n" if @debug_output
end
new_internet_message_io(s) Показать исходный код
# File lib/net/smtp.rb, line 634
def new_internet_message_io(s)
  InternetMessageIO.new(s, read_timeout: @read_timeout,
                        debug_output: @debug_output)
end
recv_response() Показать исходный код
# File lib/net/smtp.rb, line 981
def recv_response
  buf = ''.dup
  while true
    line = @socket.readline
    buf << line << "\n"
    break unless line[3,1] == '-'   # "210-PIPELINING"
  end
  Response.parse(buf)
end
ssl_socket(socket, context) Показать исходный код
# File lib/net/smtp.rb, line 614
def ssl_socket(socket, context)
  OpenSSL::SSL::SSLSocket.new socket, context
end
tcp_socket(address, port) Показать исходный код
# File lib/net/smtp.rb, line 577
def tcp_socket(address, port)
  TCPSocket.open address, port
end
tlsconnect(s, context) Показать исходный код
# File lib/net/smtp.rb, line 618
def tlsconnect(s, context)
  verified = false
  s = ssl_socket(s, context)
  logging "TLS connection started"
  s.sync_close = true
  s.hostname = @tls_hostname || @address if s.respond_to? :hostname=
  ssl_socket_connect(s, @open_timeout)
  if context.verify_mode && context.verify_mode != OpenSSL::SSL::VERIFY_NONE
    s.post_connection_check(@tls_hostname || @address)
  end
  verified = true
  s
ensure
  s.close unless verified
end
validate_line(line) Показать исходный код
# File lib/net/smtp.rb, line 958
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

Ruby Core © 1993–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API