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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With