gpt4 book ai didi

Ruby Mail,如何实现SSL邮件

转载 作者:数据小太阳 更新时间:2023-10-29 07:17:22 28 4
gpt4 key购买 nike

我已经使用此脚本使用端口 25(非安全)成功地将电子邮件发送到远程服务器:

require 'rubygems'
require 'mail'

options = { :address => "mail.domain.com",
:port => 25,
:domain => 'mail.domain.com',
:user_name => 'somedude@domain.com',
:password => 'topsecret',
:authentication => 'login',
:enable_starttls_auto => true }
Mail.defaults do
delivery_method :smtp, options
end

mail = Mail.new do
from 'someotherdude@otherdomain.com'
to 'somedude@domain.com'
subject 'This is a test email'
body File.read('body.txt')
end

puts mail.to_s
mail.deliver!

我现在需要做的是使用他们的 SSL 端口 466。当我尝试它时,我得到了详细说明消息的正常输出,然后它暂停了大约 2 分钟并吐出了这个:

/usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/timeout.rb:60:in `rbuf_fill': execution expired (Timeout::Error)
from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/protocol.rb:134:in `rbuf_fill'
from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/protocol.rb:116:in `readuntil'
from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/protocol.rb:126:in `readline'
from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:911:in `recv_response'
from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:554:in `do_start'
from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:921:in `critical'
from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:554:in `do_start'
from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:525:in `start'
from /usr/local/rvm/gems/ruby-1.8.7-p249/gems/mail-2.2.10/lib/mail/network/delivery_methods/smtp.rb:127:in `deliver!'
from /usr/local/rvm/gems/ruby-1.8.7-p249/gems/mail-2.2.10/lib/mail/message.rb:243:in `deliver!'
from testmail.rb:30

我认为这是因为它甚至无法开始 SSL 身份验证过程。我该怎么做?

最佳答案

嗯,阅读 network/delivery_methods/smtp.rb,它看起来不支持直接 SSL。 TLS 与它们不同,因为连接从纯文本开始,然后在 starttls 命令上切换到 SSL。可以只在端口 587 上使用 starttls 吗?

拉起我的评论。

How to send mail with ruby over smtp with ssl (not with rails, no TLS for gmail)

这表明您可以猴子修补 Net::SMTP 来做到这一点..

好吧,有点找到问题并可以解决它,但到目前为止这个解决方案是令人讨厌的..但它确实有效:)

#!/usr/bin/env ruby

require 'rubygems'
require "openssl"
require "net/smtp"
require "mail"

Net::SMTP.class_eval do

def self.start( address, port = nil,
helo = 'localhost.localdomain',
user = nil, secret = nil, authtype = nil, use_tls = false,
use_ssl = true, &block) # :yield: smtp
new(address, port).start(helo, user, secret, authtype, use_tls, use_ssl, &block)
end

def start( helo = 'localhost.localdomain',
user = nil, secret = nil, authtype = nil, use_tls = false, use_ssl = true ) # :yield: smtp
start_method = use_tls ? :do_tls_start : use_ssl ? :do_ssl_start : :do_start
if block_given?
begin
send start_method, helo, user, secret, authtype
return yield(self)
ensure
do_finish
end
else
send start_method, helo, user, secret, authtype
return self
end
end

private

def do_tls_start(helodomain, user, secret, authtype)
raise IOError, 'SMTP session already started' if @started

check_auth_args user, secret

sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
@socket = Net::InternetMessageIO.new(sock)
@socket.read_timeout = 60 #@read_timeout
@socket.debug_output = STDERR #@debug_output

check_response(critical { recv_response() })
do_helo(helodomain)

raise 'openssl library not installed' unless defined?(OpenSSL)
starttls
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect
@socket = Net::InternetMessageIO.new(ssl)
@socket.read_timeout = 60 #@read_timeout
@socket.debug_output = STDERR #@debug_output
do_helo(helodomain)

authenticate user, secret, authtype if user
@started = true
ensure
unless @started
# authentication failed, cancel connection.
@socket.close if not @started and @socket and not @socket.closed?
@socket = nil
end
end

def do_ssl_start(helodomain, user, secret, authtype)
raise IOError, 'SMTP session already started' if @started

check_auth_args user, secret

sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
raise 'openssl library not installed' unless defined?(OpenSSL)
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect
@socket = Net::InternetMessageIO.new(ssl)
@socket.read_timeout = 60 #@read_timeout
@socket.debug_output = STDERR #@debug_output

check_response(critical { recv_response() })
do_helo(helodomain)

do_helo(helodomain)

authenticate user, secret, authtype if user
@started = true
ensure
unless @started
# authentication failed, cancel connection.
@socket.close if not @started and @socket and not @socket.closed?
@socket = nil
end
end

def do_helo(helodomain)
begin
if @esmtp
ehlo helodomain
else
helo helodomain
end
rescue Net::ProtocolError
if @esmtp
@esmtp = false
@error_occured = false
retry
end
raise
end
end

def starttls
getok('STARTTLS')
end

def quit
begin
getok('QUIT')
rescue EOFError, OpenSSL::SSL::SSLError
end
end
end

options = {
:address => "mail.domain.net",
:port => 466,
:domain => 'mail.domain.net',
:user_name => 'doon@domain.net',
:password => 'Secret!',
:authentication => 'login',
:use_ssl => true }

Mail.defaults do
delivery_method :smtp, options
end

mail = Mail.new do
from 'doon@domain.net'
to 'doon@someotherdomain.com'
subject 'This is a test email'
body File.read('body.txt')
end

puts mail.to_s
mail.deliver!

出于某种原因,orig monkey 补丁中的 use_ssl 没有加入,并将其与 VERSION 在 Net::SMTP 中未定义相结合。所以我改变了它,并强制 use_ssl 为真,并且能够发送电子邮件..

关于Ruby Mail,如何实现SSL邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4317257/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com