Spec-Zone.ru › Ruby 2.3

класс Net::SMTP

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

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

Эта библиотека предоставляет функциональность для отправки электронной почты по протоколу SMTP (простой протокол передачи почты). Подробности о самом протоколе SMTP см. в [RFC2821] (www.ietf.org/rfc/rfc2821.txt).

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

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

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

Примеры

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

Перед отправкой сообщений необходимо открыть соединение с сервером 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

Вы также можете использовать блочный вариант ::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 домен

Практически во всех случаях вам необходимо указать третий аргумент для ::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 передайте дополнительные аргументы в ::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 178
def SMTP.default_port
  25
end

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

default_ssl_context() Показать исходный код
# File lib/net/smtp.rb, line 196
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 183
def SMTP.default_submission_port
  587
end

Номер порта отправки почты по умолчанию, 587.

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

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

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

start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... } Показать исходный код
# File lib/net/smtp.rb, line 455
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 756
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 745
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 736
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 730
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 283
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 270
def capable_cram_md5_auth?
  auth_capable?('CRAM-MD5')
end

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

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

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

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

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

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

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

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

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

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

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

Также алиасирован как: disable_ssl
ehlo(domain) Показать исходный код
# File lib/net/smtp.rb, line 834
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 336
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 345
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 299
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 534
def finish
  raise IOError, 'not yet started' unless started?
  do_finish
end

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

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

Предоставляет удобочитаемую строковую визуализацию состояния класса.

mailfrom(from_addr) Показать исходный код
# File lib/net/smtp.rb, line 838
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 714
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.

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

Параметры

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

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

Пример

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 923
def quit
  getok('QUIT')
end
rcptto(to_addr) Показать исходный код
# File lib/net/smtp.rb, line 866
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 845
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 377
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 822
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 661
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 в качестве сообщения. Одиночные символы переноса строки (“r”) и новой строки (“n”), найденные в msgstr, преобразуются в пару CR LF. Вы не можете отправить бинарное сообщение с помощью этого метода. msgstr должно содержать как заголовки сообщения, так и тело.

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

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

Пример

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 517
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 передается в блок, и автоматически закрывается после завершения вызова блока. В противном случае, ответственность за закрытие сеанса лежит на вызывающей стороне.

Пример

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

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

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

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

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

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

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

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

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

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

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

Также алиасируется как: ssl?

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

auth_capable?(type) Показать исходный код
# File lib/net/smtp.rb, line 274
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 776
def auth_method(type)
  "auth_#{type.to_s.downcase}".intern
end
base64_encode(str) Показать исходный код
# File lib/net/smtp.rb, line 789
def base64_encode(str)
  # expects "str" may not become too long
  [str].pack('m').gsub(/\s+/, '')
end
capable?(key) Показать исходный код
# File lib/net/smtp.rb, line 250
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 780
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 990
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 770
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 984
def check_auth_response(res)
  unless res.success?
    raise SMTPAuthenticationError, res.message
  end
end
check_continue(res) Показать исходный код
# File lib/net/smtp.rb, line 978
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 972
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 798
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 805
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 962
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 616
def do_finish
  quit if @socket and not @socket.closed? and not @error_occurred
ensure
  @started = false
  @error_occurred = false
  @socket.close if @socket and not @socket.closed?
  @socket = nil
end
do_helo(helo_domain) Показать исходный код
# File lib/net/smtp.rb, line 604
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 545
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 and not s.closed?
    @socket = nil
  end
end
get_response(reqline) Показать исходный код
# File lib/net/smtp.rb, line 946
def get_response(reqline)
  validate_line reqline
  @socket.writeline reqline
  recv_response()
end
getok(reqline) Показать исходный код
# File lib/net/smtp.rb, line 936
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 1075
def logging(msg)
  @debug_output << msg + "\n" if @debug_output
end
new_internet_message_io(s) Показать исходный код
# File lib/net/smtp.rb, line 597
def new_internet_message_io(s)
  io = InternetMessageIO.new(s)
  io.read_timeout = @read_timeout
  io.debug_output = @debug_output
  io
end
recv_response() Показать исходный код
# File lib/net/smtp.rb, line 952
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) Показать исходный код
# File lib/net/smtp.rb, line 578
def ssl_socket(socket, context)
  OpenSSL::SSL::SSLSocket.new socket, context
end
tcp_socket(address, port) Показать исходный код
# File lib/net/smtp.rb, line 541
def tcp_socket(address, port)
  TCPSocket.open address, port
end
tlsconnect(s) Показать исходный код
# File lib/net/smtp.rb, line 582
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 929
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