Spec-Zone.ru › Ruby 2.6

class Net::SMTP

Parent:
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,
                '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, '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
Ревизия

Атрибуты

address[R]

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

esmtp[RW]

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

esmtp?[RW]

Указывает, использовать ли 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 175
def SMTP.default_port
  25
end

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

default_ssl_context() Показать исходный код
# File lib/net/smtp.rb, line 193
def SMTP.default_ssl_context
  OpenSSL::SSL::SSLContext.new
end
default_ssl_port()
Псевдоним для: default_tls_port
default_submission_port() Показать исходный код
# File lib/net/smtp.rb, line 180
def SMTP.default_submission_port
  587
end

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

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

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

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

Создаёт новый объект 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) { |smtp| ... } Показать исходный код
# File lib/net/smtp.rb, line 452
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

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

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

Net::SMTP.new(address, port).start(helo_domain, account, password, authtype)

Пример

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 в заметках к обзору.

Ошибки

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

  • 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 751
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 740
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 731
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 725
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() Показать исходный код
# File lib/net/smtp.rb, line 280
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 267
def capable_cram_md5_auth?
  auth_capable?('CRAM-MD5')
end

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

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

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

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

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

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

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

data(msgstr = nil) { |stream| ... } Показать исходный код
# File lib/net/smtp.rb, line 891
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 393
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 351
def disable_starttls
  @starttls = false
  @ssl_context = nil
end

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

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

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

Также алиас: disable_ssl
ehlo(domain) Показать исходный код
# File lib/net/smtp.rb, line 829
def ehlo(domain)
  getok("EHLO #{domain}")
end
enable_ssl(context = SMTP.default_ssl_context)
Псевдоним для: enable_tls
enable_starttls(context = SMTP.default_ssl_context) Показать исходный код
# File lib/net/smtp.rb, line 333
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

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

enable_starttls_auto(context = SMTP.default_ssl_context) Показать исходный код
# File lib/net/smtp.rb, line 342
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

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

enable_tls(context = SMTP.default_ssl_context) Показать исходный код
# File lib/net/smtp.rb, line 296
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

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

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

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

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

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

mailfrom(from_addr) Показать исходный код
# File lib/net/smtp.rb, line 833
def mailfrom(from_addr)
  if $SAFE > 0
    raise SecurityError, 'tainted from_addr' if from_addr.tainted?
  end
  getok("MAIL FROM:<#{from_addr}>")
end
END_OF_DOCUMENT_MARKER
open_message_stream(from_addr, *to_addrs) { |stream| ... } Показать исходный код
# File lib/net/smtp.rb, line 709
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 918
def quit
  getok('QUIT')
end
rcptto(to_addr) Показать исходный код
# File lib/net/smtp.rb, line 861
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) { || ... } Показать исходный код
# File lib/net/smtp.rb, line 840
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 374
def read_timeout=(sec)
  @socket.read_timeout = sec if @socket
  @read_timeout = sec
end

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

ready(from_addr, *to_addrs)
Псевдоним для: open_message_stream
rset() Показать исходный код
# File lib/net/smtp.rb, line 817
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 656
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) { |smtp| ... } Показать исходный код
# File lib/net/smtp.rb, line 514
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

Устанавливает TCP-соединение и запускает сеанс SMTP.

Параметры

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

Если заданы и user, и secret, будет выполнена попытка аутентификации SMTP с помощью команды AUTH. authtype указывает тип аутентификации; он должен быть одним из :login, :plain и :cram_md5. См. заметки об аутентификации SMTP в общих заметках.

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

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

Пример

Это очень похоже на метод класса 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

Основное назначение этого метода (в отличие от 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 459
def started?
  @started
end

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

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

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

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

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

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

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

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

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

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

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

auth_capable?(type) Показать исходный код
# File lib/net/smtp.rb, line 271
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 771
def auth_method(type)
  "auth_#{type.to_s.downcase}".intern
end
base64_encode(str) Показать исходный код
# File lib/net/smtp.rb, line 784
def base64_encode(str)
  # expects "str" may not become too long
  [str].pack('m0')
end
capable?(key) Показать исходный код
# File lib/net/smtp.rb, line 247
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 775
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 985
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 765
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 979
def check_auth_response(res)
  unless res.success?
    raise SMTPAuthenticationError, res.message
  end
end
check_continue(res) Показать исходный код
# File lib/net/smtp.rb, line 973
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 967
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 793
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 800
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 957
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 611
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 599
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 542
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) Показать исходный код
# File lib/net/smtp.rb, line 941
def get_response(reqline)
  validate_line reqline
  @socket.writeline reqline
  recv_response()
end
getok(reqline) Показать исходный код
# File lib/net/smtp.rb, line 931
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 1070
def logging(msg)
  @debug_output << msg + "\n" if @debug_output
end
new_internet_message_io(s) Показать исходный код
# File lib/net/smtp.rb, line 594
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 947
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 575
def ssl_socket(socket, context)
  OpenSSL::SSL::SSLSocket.new socket, context
end
tcp_socket(address, port) Показать исходный код
# File lib/net/smtp.rb, line 538
def tcp_socket(address, port)
  TCPSocket.open address, port
end
tlsconnect(s) Показать исходный код
# File lib/net/smtp.rb, line 579
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) Показать исходный код
# File lib/net/smtp.rb, line 924
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–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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