mirror of https://github.com/gogits/gogs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
2.4 KiB
116 lines
2.4 KiB
package gomail |
|
|
|
import ( |
|
"errors" |
|
"fmt" |
|
"io" |
|
"net/mail" |
|
) |
|
|
|
// Sender is the interface that wraps the Send method. |
|
// |
|
// Send sends an email to the given addresses. |
|
type Sender interface { |
|
Send(from string, to []string, msg io.WriterTo) error |
|
} |
|
|
|
// SendCloser is the interface that groups the Send and Close methods. |
|
type SendCloser interface { |
|
Sender |
|
Close() error |
|
} |
|
|
|
// A SendFunc is a function that sends emails to the given addresses. |
|
// |
|
// The SendFunc type is an adapter to allow the use of ordinary functions as |
|
// email senders. If f is a function with the appropriate signature, SendFunc(f) |
|
// is a Sender object that calls f. |
|
type SendFunc func(from string, to []string, msg io.WriterTo) error |
|
|
|
// Send calls f(from, to, msg). |
|
func (f SendFunc) Send(from string, to []string, msg io.WriterTo) error { |
|
return f(from, to, msg) |
|
} |
|
|
|
// Send sends emails using the given Sender. |
|
func Send(s Sender, msg ...*Message) error { |
|
for i, m := range msg { |
|
if err := send(s, m); err != nil { |
|
return fmt.Errorf("gomail: could not send email %d: %v", i+1, err) |
|
} |
|
} |
|
|
|
return nil |
|
} |
|
|
|
func send(s Sender, m *Message) error { |
|
from, err := m.getFrom() |
|
if err != nil { |
|
return err |
|
} |
|
|
|
to, err := m.getRecipients() |
|
if err != nil { |
|
return err |
|
} |
|
|
|
if err := s.Send(from, to, m); err != nil { |
|
return err |
|
} |
|
|
|
return nil |
|
} |
|
|
|
func (m *Message) getFrom() (string, error) { |
|
from := m.header["Sender"] |
|
if len(from) == 0 { |
|
from = m.header["From"] |
|
if len(from) == 0 { |
|
return "", errors.New(`gomail: invalid message, "From" field is absent`) |
|
} |
|
} |
|
|
|
return parseAddress(from[0]) |
|
} |
|
|
|
func (m *Message) getRecipients() ([]string, error) { |
|
n := 0 |
|
for _, field := range []string{"To", "Cc", "Bcc"} { |
|
if addresses, ok := m.header[field]; ok { |
|
n += len(addresses) |
|
} |
|
} |
|
list := make([]string, 0, n) |
|
|
|
for _, field := range []string{"To", "Cc", "Bcc"} { |
|
if addresses, ok := m.header[field]; ok { |
|
for _, a := range addresses { |
|
addr, err := parseAddress(a) |
|
if err != nil { |
|
return nil, err |
|
} |
|
list = addAddress(list, addr) |
|
} |
|
} |
|
} |
|
|
|
return list, nil |
|
} |
|
|
|
func addAddress(list []string, addr string) []string { |
|
for _, a := range list { |
|
if addr == a { |
|
return list |
|
} |
|
} |
|
|
|
return append(list, addr) |
|
} |
|
|
|
func parseAddress(field string) (string, error) { |
|
addr, err := mail.ParseAddress(field) |
|
if err != nil { |
|
return "", fmt.Errorf("gomail: invalid address %q: %v", field, err) |
|
} |
|
return addr.Address, nil |
|
}
|
|
|