класс Net::SMTP
Что представляет собой эта библиотека?
Эта библиотека предоставляет возможность отправлять электронную почту по протоколу 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
Атрибуты
Адрес сервера SMTP для подключения.
Секунды ожидания при попытке открытия подключения. Если подключение не может быть открыто в течение этого времени, генерируется исключение Net::OpenTimeout. Значение по умолчанию — 30 секунд.
Порт сервера SMTP для подключения.
Секунды ожидания при чтении одного блока (одним вызовом read(2)). Если вызов read(2) не завершится в течение этого времени, генерируется исключение Net::ReadTimeout. Значение по умолчанию — 60 секунд.
Методы публичного класса
# File lib/net/smtp.rb, line 176 def SMTP.default_port 25 end
Порт по умолчанию сервера SMTP, 25.
# 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
# File lib/net/smtp.rb, line 181 def SMTP.default_submission_port 587 end
Порт по умолчанию для отправки почты, 587.
# File lib/net/smtp.rb, line 186 def SMTP.default_tls_port 465 end
Порт по умолчанию SMTPS, 465.
# 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.
# 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.
Ошибки
Этот метод может вызывать следующие ошибки:
Общедоступные методы экземпляров
# 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 # 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 # 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 # 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
# File lib/net/smtp.rb, line 287 def capable_auth_types return [] unless @capabilities return [] unless @capabilities['AUTH'] @capabilities['AUTH'] end
Возвращает поддерживаемые методы аутентификации на данном сервере. Вы не сможете получить корректное значение до открытия сессии SMTP.
# File lib/net/smtp.rb, line 274
def capable_cram_md5_auth?
auth_capable?('CRAM-MD5')
end true, если сервер поддерживает AUTH CRAM-MD5. Вы не сможете получить корректное значение до открытия сессии SMTP.
# File lib/net/smtp.rb, line 268
def capable_login_auth?
auth_capable?('LOGIN')
end true, если сервер поддерживает AUTH LOGIN. Вы не сможете получить корректное значение до открытия сессии SMTP.
# File lib/net/smtp.rb, line 262
def capable_plain_auth?
auth_capable?('PLAIN')
end true, если сервер поддерживает AUTH PLAIN. Вы не сможете получить корректное значение до открытия сессии SMTP.
# File lib/net/smtp.rb, line 250
def capable_starttls?
capable?('STARTTLS')
end true, если сервер поддерживает STARTTLS. Вы не сможете получить корректное значение до открытия сессии SMTP сессии.
# 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."
}
# 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
# File lib/net/smtp.rb, line 358 def disable_starttls @starttls = false @ssl_context_starttls = nil end
Отключает SMTP/TLS (STARTTLS) для данного объекта. Необходимо вызвать этот метод до установления соединения, чтобы он подействовал.
# File lib/net/smtp.rb, line 314 def disable_tls @tls = false @ssl_context_tls = nil end
Отключает SMTP/TLS для данного объекта. Необходимо вызвать этот метод до установления соединения, чтобы он подействовал.
# File lib/net/smtp.rb, line 869
def ehlo(domain)
getok("EHLO #{domain}")
end # 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.
# 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.
# 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.
# File lib/net/smtp.rb, line 865
def helo(domain)
getok("HELO #{domain}")
end # File lib/net/smtp.rb, line 232
def inspect
"#<#{self.class} #{@address}:#{@port} started=#{@started}>"
end Возвращает удобочитаемое строковое представление состояния класса.
# File lib/net/smtp.rb, line 873
def mailfrom(from_addr)
getok("MAIL FROM:<#{from_addr}>")
end # 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
Ошибки
Этот метод может вызвать:
# File lib/net/smtp.rb, line 952
def quit
getok('QUIT')
end # File lib/net/smtp.rb, line 898
def rcptto(to_addr)
getok("RCPT TO:<#{to_addr}>")
end # 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 # File lib/net/smtp.rb, line 381 def read_timeout=(sec) @socket.read_timeout = sec if @socket @read_timeout = sec end
Set количество секунд ожидания при таймауте вызова read(2).
# File lib/net/smtp.rb, line 857
def rset
getok('RSET')
end Прерывает текущую транзакцию отправки почты.
# 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
Ошибки
Этот метод может вызвать:
# 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.
Этот метод может вызвать:
# File lib/net/smtp.rb, line 479 def started? @started end
Возвращает true, если сеанс SMTP запущен.
# File lib/net/smtp.rb, line 861
def starttls
getok('STARTTLS')
end # File lib/net/smtp.rb, line 324 def starttls? @starttls end
Возвращает логическое значение, если этот объект использует STARTTLS. Если этот объект всегда использует STARTTLS, возвращает :always. Если этот объект использует STARTTLS, когда сервер поддерживает TLS, возвращает :auto.
# File lib/net/smtp.rb, line 329 def starttls_always? @starttls == :always end
true, если этот объект использует STARTTLS.
# File lib/net/smtp.rb, line 334 def starttls_auto? @starttls == :auto end
true, если этот объект использует STARTTLS, когда сервер объявляет STARTTLS.
# File lib/net/smtp.rb, line 294 def tls? @tls end
true, если этот объект использует SMTP/TLS (SMTPS).
Приватные методы экземпляра
# 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
# File lib/net/smtp.rb, line 811
def auth_method(type)
"auth_#{type.to_s.downcase}".intern
end # File lib/net/smtp.rb, line 824
def base64_encode(str)
# expects "str" may not become too long
[str].pack('m0')
end # File lib/net/smtp.rb, line 254 def capable?(key) return nil unless @capabilities @capabilities[key] ? true : false end
# 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 # File lib/net/smtp.rb, line 1019
def check_auth_continue(res)
unless res.continue?
raise res.exception_class, res.message
end
end # 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 # File lib/net/smtp.rb, line 1013
def check_auth_response(res)
unless res.success?
raise SMTPAuthenticationError, res.message
end
end # 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 # File lib/net/smtp.rb, line 1001
def check_response(res)
unless res.success?
raise res.exception_class, res.message
end
end # 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]
# 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 # 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 # 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
# 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 # 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 # File lib/net/smtp.rb, line 975 def get_response(reqline) validate_line reqline @socket.writeline reqline recv_response() end
# 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 # File lib/net/smtp.rb, line 1104 def logging(msg) @debug_output << msg + "\n" if @debug_output end
# 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 # 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 # File lib/net/smtp.rb, line 614 def ssl_socket(socket, context) OpenSSL::SSL::SSLSocket.new socket, context end
# File lib/net/smtp.rb, line 577 def tcp_socket(address, port) TCPSocket.open address, port end
# 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 # 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.