EOFError 错误尝试通过带有 Rails 3.1.3 的 SMTP 使用 Amazon SES
Posted
技术标签:
【中文标题】EOFError 错误尝试通过带有 Rails 3.1.3 的 SMTP 使用 Amazon SES【英文标题】:EOFError error trying to use Amazon SES via SMTP with Rails 3.1.3 【发布时间】:2012-01-24 09:21:02 【问题描述】:我有一个 Rails 应用程序配置为通过 SMTP 使用 Amazon SES。但是,当我尝试发送电子邮件时,它似乎在一分钟后超时,并且我收到了 EOFError。闻起来像是配置问题——电子邮件似乎构造良好,我可以从 AWS SES 控制台向自己发送测试电子邮件。这是在沙盒模式下,应用程序在开发模式下运行,但发送和接收电子邮件都已通过 SES 验证,并且 development.rb 是这样设置的:
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
我已经尝试了一百万种配置变体;这开始让我发疯了。任何帮助或指导将非常非常感激。更多详情:
我在初始化程序中的 smtp 配置:
ActionMailer::Base.smtp_settings =
:address => "email-smtp.us-east-1.amazonaws.com",
:port => "465",
:authentication => :plain,
:enable_starttls_auto => true,
:user_name => "1234",
:password => "abcde"
有错误的日志,为简洁起见被截断:
Sent mail to john@phu.com (59929ms)
Date: Tue, 20 Dec 2011 03:08:37 -0800
From: contact@phu.com
To: john@phu.com
Message-ID: <4ef06cb5ed3c_d73c3fc604c34d4491943@Johns-MacBook-Pro.local.mail>
Subject: Your invitation to Phu
Mime-Version: 1.0
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: 7bit
<!DOCTYPE html>
....
Completed 500 Internal Server Error in 60564ms
EOFError (end of file reached):
app/controllers/admin_controller.rb:61:in `block in send_invite'
app/controllers/admin_controller.rb:46:in `send_invite'
【问题讨论】:
您的 ISP 是否允许端口 465 上的出站连接?您可以将您的亚马逊 smtp 凭证与普通邮件客户端一起使用吗? 你让它工作了吗?因为我有同样的问题... 还没有开始工作——最终通过 smpt 使用 Gmail,这暂时已经足够好了。我将在下面尝试 Mihir 的解决方案并报告(如果可行,请接受答案)。 Frederick,我可以在 Rails 之外使用 smtp——这是我自己的服务器实例,端口是开放的。 【参考方案1】:还有一个没有来自 Mihir 的猴子补丁解决方案的解决方案(根据 AWS SES 文档,http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/SMTP.Connecting.html 是 TLS 包装器解决方案),使用端口 587 和 :enable_starttls_auto 选项(STARTTLS 解决方案)。所以修改后的配置是这样的:
config.action_mailer.default_url_options = host: “<example.com>”
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings =
:address: “email-smtp.us-east-1.amazonaws.com”,
:port: 587,
:domain: “<example.com>”,
:authentication: :login,
:user_name: “<your aws smtp username>”,
:password: “<your aws smtp password>”,
:enable_starttls_auto => true
【讨论】:
根据docs,端口465用于ssmtp(smtp over SSL)。对于带有 STARTTLS 的 SMTP,您需要使用您发现的端口 25 或 587。【参考方案2】:如果您想使用 SMTP(而不是 AWS-SES gem),这是一个解决方案
http://blog.readypulse.com/2012/01/06/amazon-ses-smtp-emails-using-rails-3-1-in-three-easy-steps/
注意事项
AWS SMTP 仅适用于 TLS AWS SMTP 不支持 STARTTLS ActionMailer 的配置没有简单的 TLS 开关。 后续步骤
在您的 AWS 控制台上启用 SMTP 支持 – 请参阅此处的说明。 在 config/initializers 目录下创建一个初始化程序。我将其命名为 amazon_ses.rb 并将以下代码添加到资金补丁 ActionMailer 的 SMTP 设置中。
module Net
class SMTP
def tls?
true
end
end
end
在您的 development.rb 和 production.rb 文件中添加以下代码。修改设置以匹配您的环境。
config.action_mailer.default_url_options = host: “<example.com>”
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings =
address: “email-smtp.us-east-1.amazonaws.com”,
port: 465,
domain: “<example.com>”,
authentication: :login,
user_name: “<your aws smtp username>”,
password: “<your aws smtp password>”
【讨论】:
当我将模块更改与邮件设置放在同一个文件中时,我得到了这个工作。 (在 Rails 3.2 上)我必须将require 'net/smtp'
添加到初始化文件的顶部(module Net
上方)。我认为它正在加载初始化程序,然后稍后加载实际的库,覆盖猴子补丁。
这对我有用,添加了以下 smtp_settings: :openssl_verify_mode => OpenSSL::SSL::VERIFY_NONE, :enable_starttls_auto => true 我正在使用 Ruby 1.8.7 和 Rails 2.3.5
在我的测试中(Ruby 1.8.7、Rails 2.3.15),当使用端口 25 和 465 时需要此补丁,但对于 587 则不需要。
不幸的是,对我来说唯一的解决方案就是这个猴子补丁【参考方案3】:
我在开发模式下使用 Rails 2.3 和 Ruby 1.8.7 并使用沙盒 SES 帐户向/从经过验证的发件人发送数据时遇到了同样的问题。
我通过添加unofficial aws-ses gem 解决了这个问题。将其粘贴到您的 Gemfile 中,然后将 smtp 设置替换为以下 5 行:
# Configure mail sending options: Use AWS-SES for all environments
config.after_initialize do
ActionMailer::Base.delivery_method = :amazon_ses
ActionMailer::Base.custom_amazon_ses_mailer = AWS::SES::Base.new(:secret_access_key => 'asfd/1234', :access_key_id => 'ABCD')
end
然后发送按预期工作......这告诉我电子邮件本身设置正确。
我进行了很多谷歌搜索,但没有看到任何确认 SES-SMTP 与 Rails 2.3 + Ruby 1.8.7 兼容。除了您和我的经验之外,我也没有发现任何明确否认它的东西。
如果您找到解决方案,请告诉我们!
【讨论】:
【参考方案4】:在发送 EHLO 命令之前,SES 需要 SSL 会话。
我知道 System.Net.Mail 不适用于 SES,因为 System.Net.Mail 在 SMTP 会话开始后启动 TLS。
【讨论】:
感谢您的建议,但如果我正确阅读 this commit,ActionMailer(Rails 等效于 System.Net.Mail)会在开始会话之前启动 TLS。【参考方案5】:我在 Rails 3.2.12 上进行了这项工作,将 require 'net/smtp' 添加到初始化程序文件中,模块更改如下:
require 'net/smtp'
module Net
class SMTP
def tls?
true
end
end
end
【讨论】:
以上是关于EOFError 错误尝试通过带有 Rails 3.1.3 的 SMTP 使用 Amazon SES的主要内容,如果未能解决你的问题,请参考以下文章
Rails 4:EOFError:仅在开发中的任何电子邮件后到达文件结尾