@ -11,6 +11,7 @@ import (
"net"
"net"
"net/smtp"
"net/smtp"
"os"
"os"
"os/exec"
"strings"
"strings"
"time"
"time"
@ -87,12 +88,12 @@ func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
return nil , nil
return nil , nil
}
}
// Sender mail sender
// Sender SMTP mail sender
type Sender struct {
type smtp Sender struct {
}
}
// Send send email
// Send send email
func ( s * Sender ) Send ( from string , to [ ] string , msg io . WriterTo ) error {
func ( s * smtp Sender) Send ( from string , to [ ] string , msg io . WriterTo ) error {
opts := setting . MailService
opts := setting . MailService
host , port , err := net . SplitHostPort ( opts . Host )
host , port , err := net . SplitHostPort ( opts . Host )
@ -195,14 +196,51 @@ func (s *Sender) Send(from string, to []string, msg io.WriterTo) error {
return client . Quit ( )
return client . Quit ( )
}
}
func processMailQueue ( ) {
// Sender sendmail mail sender
sender := & Sender { }
type sendmailSender struct {
}
// Send send email
func ( s * sendmailSender ) Send ( from string , to [ ] string , msg io . WriterTo ) error {
var err error
var closeError error
var waitError error
args := [ ] string { "-F" , from , "-i" }
args = append ( args , to ... )
log . Trace ( "Sending with: %s %v" , setting . MailService . SendmailPath , args )
cmd := exec . Command ( setting . MailService . SendmailPath , args ... )
pipe , err := cmd . StdinPipe ( )
if err != nil {
return err
}
if err = cmd . Start ( ) ; err != nil {
return err
}
_ , err = msg . WriteTo ( pipe )
// we MUST close the pipe or sendmail will hang waiting for more of the message
// Also we should wait on our sendmail command even if something fails
closeError = pipe . Close ( )
waitError = cmd . Wait ( )
if err != nil {
return err
} else if closeError != nil {
return closeError
} else {
return waitError
}
}
func processMailQueue ( ) {
for {
for {
select {
select {
case msg := <- mailQueue :
case msg := <- mailQueue :
log . Trace ( "New e-mail sending request %s: %s" , msg . GetHeader ( "To" ) , msg . Info )
log . Trace ( "New e-mail sending request %s: %s" , msg . GetHeader ( "To" ) , msg . Info )
if err := gomail . Send ( sender , msg . Message ) ; err != nil {
if err := gomail . Send ( S ender, msg . Message ) ; err != nil {
log . Error ( 3 , "Fail to send emails %s: %s - %v" , msg . GetHeader ( "To" ) , msg . Info , err )
log . Error ( 3 , "Fail to send emails %s: %s - %v" , msg . GetHeader ( "To" ) , msg . Info , err )
} else {
} else {
log . Trace ( "E-mails sent %s: %s" , msg . GetHeader ( "To" ) , msg . Info )
log . Trace ( "E-mails sent %s: %s" , msg . GetHeader ( "To" ) , msg . Info )
@ -213,6 +251,9 @@ func processMailQueue() {
var mailQueue chan * Message
var mailQueue chan * Message
// Sender sender for sending mail synchronously
var Sender gomail . Sender
// NewContext start mail queue service
// NewContext start mail queue service
func NewContext ( ) {
func NewContext ( ) {
// Need to check if mailQueue is nil because in during reinstall (user had installed
// Need to check if mailQueue is nil because in during reinstall (user had installed
@ -222,6 +263,13 @@ func NewContext() {
return
return
}
}
if setting . MailService . UseSendmail {
Sender = & sendmailSender { }
} else {
Sender = & smtpSender { }
}
mailQueue = make ( chan * Message , setting . MailService . QueueLength )
mailQueue = make ( chan * Message , setting . MailService . QueueLength )
go processMailQueue ( )
go processMailQueue ( )
}
}