1 package mail
2
3 import (
4 "errors"
5 "fmt"
6 "io"
7 stdmail "net/mail"
8 )
9
10
11
12
13 type Sender interface {
14 Send(from string, to []string, msg io.WriterTo) error
15 }
16
17
18 type SendCloser interface {
19 Sender
20 Close() error
21 }
22
23
24
25
26
27
28 type SendFunc func(from string, to []string, msg io.WriterTo) error
29
30
31 func (f SendFunc) Send(from string, to []string, msg io.WriterTo) error {
32 return f(from, to, msg)
33 }
34
35
36 func Send(s Sender, msg ...*Message) error {
37 for i, m := range msg {
38 if err := send(s, m); err != nil {
39 return &SendError{Cause: err, Index: uint(i)}
40 }
41 }
42
43 return nil
44 }
45
46 func send(s Sender, m *Message) error {
47 from, err := m.getFrom()
48 if err != nil {
49 return err
50 }
51
52 to, err := m.getRecipients()
53 if err != nil {
54 return err
55 }
56
57 if err := s.Send(from, to, m); err != nil {
58 return err
59 }
60
61 return nil
62 }
63
64 func (m *Message) getFrom() (string, error) {
65 from := m.header["Sender"]
66 if len(from) == 0 {
67 from = m.header["From"]
68 if len(from) == 0 {
69 return "", errors.New(`gomail: invalid message, "From" field is absent`)
70 }
71 }
72
73 return parseAddress(from[0])
74 }
75
76 func (m *Message) getRecipients() ([]string, error) {
77 n := 0
78 for _, field := range []string{"To", "Cc", "Bcc"} {
79 if addresses, ok := m.header[field]; ok {
80 n += len(addresses)
81 }
82 }
83 list := make([]string, 0, n)
84
85 for _, field := range []string{"To", "Cc", "Bcc"} {
86 if addresses, ok := m.header[field]; ok {
87 for _, a := range addresses {
88 addr, err := parseAddress(a)
89 if err != nil {
90 return nil, err
91 }
92 list = addAddress(list, addr)
93 }
94 }
95 }
96
97 return list, nil
98 }
99
100 func addAddress(list []string, addr string) []string {
101 for _, a := range list {
102 if addr == a {
103 return list
104 }
105 }
106
107 return append(list, addr)
108 }
109
110 func parseAddress(field string) (string, error) {
111 addr, err := stdmail.ParseAddress(field)
112 if err != nil {
113 return "", fmt.Errorf("gomail: invalid address %q: %v", field, err)
114 }
115 return addr.Address, nil
116 }
117
View as plain text