在GO中发送电子邮件时,无法设置Return-Path头部。

huangapple go评论102阅读模式
英文:

Email sending in GO, unable to set Return-Path header

问题

我正在尝试使用smtp包的内置功能从GO发送简单的电子邮件。

我的简单代码如下:

func sendEmail(to string, body []byte) error {
    auth := smtp.PlainAuth(
        "",
        config.SmtpUsername,
        config.SmtpPassword,
        config.SmtpHostname,
    )

    return smtp.SendMail(
        fmt.Sprintf("%s:%d", config.SmtpHostname, config.SmtpPort),
        auth,
        config.SmtpUsername,
        []string{to},
        body,
    )
}

它可以工作,但问题是,即使我发送包含自定义Return-Path头的消息,它始终将Return-Path头设置为config.SmtpUsername的值。基本上,在消息发送后,似乎以某种方式将消息中的Return-Path替换为smtp用户名。

你有什么想法,我如何避免这种情况,让GO使用我提供的任何Return-Path?

附加代码:

使用SwiftMailer的PHP,它设置了正确的返回路径:

Yii::import('common.vendors.SwiftMailer.lib.classes.Swift', true);
Yii::registerAutoloader(array('Swift', 'autoload'));
Yii::import('common.vendors.SwiftMailer.lib.swift_init', true);

$hostname   = '';
$username   = '';
$password   = '';
$returnPath = '';
$subject    = 'Swiftmailer sending, test return path';
$toEmail    = '';

$transport = Swift_SmtpTransport::newInstance($hostname, 25);
$transport->setUsername($username);
$transport->setPassword($password);

$logger  = new Swift_Plugins_LoggerPlugin(new Swift_Plugins_Loggers_ArrayLogger());
$mailer  = Swift_Mailer::newInstance($transport);
$mailer->registerPlugin($logger);

$message = Swift_Message::newInstance();

$message->setReturnPath($returnPath);
$message->setSubject($subject);
$message->setFrom($username);
$message->setTo($toEmail);
$message->setBody('Hello, this is a simple test going on here...');

$sent = $mailer->send($message);

print_r($logger->dump());

使用自定义的mysmtp包的GO代码,我只需在tls配置中设置InsecureSkipVerify: true以避免证书错误,但返回路径仍然错误:

hostname := ""
username := ""
password := ""
returnPath := ""
subject := "GO sending, test return path"
toEmail := ""
body := "Hello, this is a simple test going on here..."

auth := mysmtp.PlainAuth(
    "",
    username,
    password,
    hostname,
)

header := make(map[string]string)
header["Return-Path"] = returnPath
header["From"] = username
header["To"] = toEmail
header["Subject"] = subject

message := ""
for k, v := range header {
    message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + string([]byte(body))

err := mysmtp.SendMail(
    fmt.Sprintf("%s:%d", hostname, 25),
    auth,
    username,
    []string{toEmail},
    []byte(message),
)

log.Fatal(err)

我真的不知道哪里出错了,为什么会出错。最后一个测试是针对postfix mta进行的,我只是从postfix配置中删除了reject_sender_login_mismatch策略,以允许这种行为。

英文:

I am trying to send a simple email from GO using the built-in functionality of smtp package.

My simple code looks like:

func sendEmail(to string, body []byte) error {
    auth := smtp.PlainAuth(
	    "",
	    config.SmtpUsername,
	    config.SmtpPassword,
	    config.SmtpHostname,
    )

    return smtp.SendMail(
	    fmt.Sprintf("%s:%d", config.SmtpHostname, config.SmtpPort),
	    auth,
	    config.SmtpUsername,
	    []string{to},
	    body,
    ) 
}

And it works, the thing is that it always sets the Return-Path header to value of the config.SmtpUsername even if i send a message that contains custom Return-Path header, basically after the message is sent, seems that somehow the Return-Path from the message is replaced with the smtp username.

Any thoughts on how i could avoid this and make GO use whatever Return-Path i give?

L.E 1: If any help, a code snippet is available at: http://play.golang.org/p/ATDCgJGKZ3
L.E 2: I can achieve the desired behavior from php with swiftmailer, thus i don't think the delivery server is changing the headers in any way.

More code:

PHP with swiftmailer, it sets proper return path:

Yii::import('common.vendors.SwiftMailer.lib.classes.Swift', true);
Yii::registerAutoloader(array('Swift', 'autoload'));
Yii::import('common.vendors.SwiftMailer.lib.swift_init', true);

$hostname   = '';
$username   = '';
$password   = '';
$returnPath = '';
$subject    = 'Swiftmailer sending, test return path';
$toEmail    = '';

$transport = Swift_SmtpTransport::newInstance($hostname, 25);
$transport->setUsername($username);
$transport->setPassword($password);

$logger  = new Swift_Plugins_LoggerPlugin(new Swift_Plugins_Loggers_ArrayLogger());
$mailer  = Swift_Mailer::newInstance($transport);
$mailer->registerPlugin($logger);

$message = Swift_Message::newInstance();

$message->setReturnPath($returnPath);
$message->setSubject($subject);
$message->setFrom($username);
$message->setTo($toEmail);
$message->setBody('Hello, this is a simple test going on here...');

$sent = $mailer->send($message);

print_r($logger->dump());   

GO with a custom mysmtp package, where i just set InsecureSkipVerify: true in tls configuration to avoid certificate errors, still the return path is wrong :

hostname := ""
username := ""
password := ""
returnPath := ""
subject := "GO sending, test return path"
toEmail := ""
body := "Hello, this is a simple test going on here..."

auth := mysmtp.PlainAuth(
	"",
	username,
	password,
	hostname,
)

header := make(map[string]string)
header["Return-Path"] = returnPath
header["From"] = username
header["To"] = toEmail
header["Subject"] = subject

message := ""
for k, v := range header {
	message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + string([]byte(body))

err := mysmtp.SendMail(
	fmt.Sprintf("%s:%d", hostname, 25),
	auth,
	username,
	[]string{toEmail},
	[]byte(message),
)

log.Fatal(err)

I literally have no clue what fails and why, this last test has been conducted against a postfix mta, where i just removed the reject_sender_login_mismatch policy from postfix configuration to allow this behavior.

答案1

得分: 5

Return-Path是从客户端在发送消息时指定的“MAIL FROM”命令中派生的。

通过查看smtp包的实现细节,可以在http://golang.org/src/pkg/net/smtp/smtp.go中实现一个SendMail函数,该函数可以在func (c *Client) Mail(from string) error的参数中使用替代地址。

英文:

The Return-Path is derived from the "MAIL FROM" command that the client specifies when sending the message.

Looking at the implementation details of the smtp package at http://golang.org/src/pkg/net/smtp/smtp.go it should not be too difficult to implement a SendMail function that uses an alternative address for the argument of func (c *Client) Mail(from string) error.

huangapple
  • 本文由 发表于 2014年7月25日 23:09:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/24958882.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定