Merge branch 'master' of http://gitlab.fjmaimaimai.com/mmm-go/gocomm
正在显示
4 个修改的文件
包含
180 行增加
和
0 行删除
goemail/auth.go
0 → 100644
1 | +package goemail | ||
2 | + | ||
3 | +import ( | ||
4 | + "bytes" | ||
5 | + "errors" | ||
6 | + "fmt" | ||
7 | + "net/smtp" | ||
8 | +) | ||
9 | + | ||
10 | +//loginAuth实现smtp.Auth的接口,实现登录身份验证机制的验证. | ||
11 | +//扩展net/smtp中实现的认证机制,net/smtp中仅实现了PlainAuth和CRAMMD5Auth | ||
12 | +type loginAuth struct { | ||
13 | + username string | ||
14 | + password string | ||
15 | + host string | ||
16 | +} | ||
17 | + | ||
18 | +var _ smtp.Auth = &loginAuth{} | ||
19 | + | ||
20 | +func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) { | ||
21 | + if !server.TLS { | ||
22 | + advertised := false | ||
23 | + for _, mechanism := range server.Auth { | ||
24 | + if mechanism == "LOGIN" { | ||
25 | + advertised = true | ||
26 | + break | ||
27 | + } | ||
28 | + } | ||
29 | + if !advertised { | ||
30 | + return "", nil, errors.New("mail: unencrypted connection") | ||
31 | + } | ||
32 | + } | ||
33 | + if server.Name != a.host { | ||
34 | + return "", nil, errors.New("mail: wrong host name") | ||
35 | + } | ||
36 | + return "LOGIN", nil, nil | ||
37 | +} | ||
38 | + | ||
39 | +func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) { | ||
40 | + if !more { | ||
41 | + return nil, nil | ||
42 | + } | ||
43 | + | ||
44 | + switch { | ||
45 | + case bytes.EqualFold(fromServer, []byte("Username:")): | ||
46 | + return []byte(a.username), nil | ||
47 | + case bytes.EqualFold(fromServer, []byte("Password:")): | ||
48 | + return []byte(a.password), nil | ||
49 | + default: | ||
50 | + return nil, fmt.Errorf("mail: unexpected server challenge: %s", fromServer) | ||
51 | + } | ||
52 | +} |
goemail/email.go
0 → 100644
1 | +package goemail | ||
2 | + | ||
3 | +import ( | ||
4 | + "net/smtp" | ||
5 | +) | ||
6 | + | ||
7 | +// ServerHost string //邮箱服务器地址 | ||
8 | +// ServerPort string //邮箱服务器的端口 | ||
9 | +// FromPasswd string //密码 | ||
10 | + | ||
11 | +//NewPlainAuth | ||
12 | +func NewPlainAuth(fromEmail string, pwd string, host string) smtp.Auth { | ||
13 | + return smtp.PlainAuth("", fromEmail, pwd, host) | ||
14 | +} | ||
15 | + | ||
16 | +func NewLoginAuth(fromEmail string, pwd string, host string) smtp.Auth { | ||
17 | + return &loginAuth{ | ||
18 | + username: fromEmail, | ||
19 | + password: pwd, | ||
20 | + host: host, | ||
21 | + } | ||
22 | +} | ||
23 | + | ||
24 | +func Send(addr string, auth smtp.Auth, m *EmailMessage) error { | ||
25 | + return smtp.SendMail(addr, auth, m.FromEmail, m.Toers, m.Bytes()) | ||
26 | +} |
goemail/email_test.go
0 → 100644
1 | +package goemail | ||
2 | + | ||
3 | +import "testing" | ||
4 | + | ||
5 | +const ( | ||
6 | + testTo1 = "" | ||
7 | + testTo2 = "to2@example.com" | ||
8 | + testFrom = "" | ||
9 | + testpwd = "" | ||
10 | + testBody = "Test message" | ||
11 | + testMsg = "To: " + testTo1 + ", " + testTo2 + "\r\n" + | ||
12 | + "From: " + testFrom + "\r\n" + | ||
13 | + "Mime-Version: 1.0\r\n" + | ||
14 | + "Date: Wed, 25 Jun 2014 17:46:00 +0000\r\n" + | ||
15 | + "Content-Type: text/plain; charset=UTF-8\r\n" + | ||
16 | + "Content-Transfer-Encoding: quoted-printable\r\n" + | ||
17 | + "\r\n" + | ||
18 | + testBody | ||
19 | +) | ||
20 | + | ||
21 | +func TestSend(T *testing.T) { | ||
22 | + m := &EmailMessage{ | ||
23 | + FromEmail: testFrom, | ||
24 | + Toers: []string{testTo1}, | ||
25 | + Subject: "测试邮件", | ||
26 | + BodyContentType: "text/html", | ||
27 | + Body: []byte(testBody), | ||
28 | + } | ||
29 | + auth := NewLoginAuth(testFrom, testpwd, "smtp.163.com") | ||
30 | + err := Send("smtp.163.com:25", auth, m) | ||
31 | + if err != nil { | ||
32 | + T.Error(err) | ||
33 | + } | ||
34 | +} |
goemail/message.go
0 → 100644
1 | +package goemail | ||
2 | + | ||
3 | +import ( | ||
4 | + "bytes" | ||
5 | + "encoding/base64" | ||
6 | + "fmt" | ||
7 | + "strings" | ||
8 | + "time" | ||
9 | +) | ||
10 | + | ||
11 | +type EmailHeader struct { | ||
12 | + Key string | ||
13 | + Value string | ||
14 | +} | ||
15 | + | ||
16 | +type EmailMessage struct { | ||
17 | + FromEmail string //发件人邮箱地址 | ||
18 | + // Header []EmailHeader | ||
19 | + Toers []string //邮件接收人,如有多个,则以英文逗号(“,”)隔开,不能为空 | ||
20 | + Subject string //主题 | ||
21 | + BodyContentType string //默认值text/html | ||
22 | + BodyCharset string //字符编码设定默认utf-8 | ||
23 | + Body []byte //邮件正文内容 | ||
24 | + //TODO 添加附件 | ||
25 | +} | ||
26 | + | ||
27 | +func (e *EmailMessage) AddToer(v string) { | ||
28 | + e.Toers = append(e.Toers, v) | ||
29 | +} | ||
30 | + | ||
31 | +func (e *EmailMessage) SetBody(v []byte) { | ||
32 | + e.Body = v | ||
33 | +} | ||
34 | + | ||
35 | +func (e *EmailMessage) SetBodyContentType(v string) { | ||
36 | + e.BodyContentType = v | ||
37 | +} | ||
38 | + | ||
39 | +func (e *EmailMessage) SetBodyCharset(v string) { | ||
40 | + e.BodyCharset = v | ||
41 | +} | ||
42 | + | ||
43 | +func (e *EmailMessage) Bytes() []byte { | ||
44 | + buf := bytes.NewBuffer(nil) | ||
45 | + buf.WriteString(fmt.Sprintf("From:%s \r\n", e.FromEmail)) | ||
46 | + t := time.Now().Format(time.RFC1123Z) | ||
47 | + buf.WriteString(fmt.Sprintf("Date:%s \r\n", t)) | ||
48 | + buf.WriteString(fmt.Sprintf("To:%s \r\n", strings.Join(e.Toers, ","))) | ||
49 | + var subject = "=?UTF-8?B?" + base64.StdEncoding.EncodeToString([]byte(e.Subject)) + "?=" | ||
50 | + buf.WriteString("Subject: " + subject + "\r\n") | ||
51 | + buf.WriteString("MIME-Version: 1.0\r\n") | ||
52 | + //TODO 添加header | ||
53 | + boundary := "THIS_IS_BOUNDARY" | ||
54 | + buf.WriteString("Content-Type: multipart/mixed; boundary=" + boundary + "\r\n") | ||
55 | + buf.WriteString("\r\n--" + boundary + "\r\n") | ||
56 | + buf.WriteString(fmt.Sprintf("Content-Type: %s; charset=%s\r\n\r\n", e.BodyContentType, e.BodyCharset)) | ||
57 | + buf.Write(e.Body) | ||
58 | + buf.WriteString("\r\n") | ||
59 | + buf.WriteString("--" + boundary + "--") | ||
60 | + //TODO添加附件 | ||
61 | + return buf.Bytes() | ||
62 | +} | ||
63 | + | ||
64 | +// func (e *EmailMessage) AddHeader(key string, value string) EmailHeader { | ||
65 | +// newHeader := EmailHeader{Key: key, Value: value} | ||
66 | +// e.Header = append(e.Header, newHeader) | ||
67 | +// return newHeader | ||
68 | +// } |
-
请 注册 或 登录 后发表评论