forked from pereiro/smtprelay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmessage.go
98 lines (87 loc) · 2.08 KB
/
message.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package main
import (
"bytes"
"errors"
"fmt"
"smtprelay/uuid"
"net/mail"
"strings"
)
type EmailAddress struct {
RawAddress string
Address string
Alias string
Domain string
}
type Msg struct {
Rcpt []EmailAddress
Sender EmailAddress
RcptDomains map[string]int
MessageId string
Message mail.Message
}
func (msg *Msg) String() string {
var rcpt string
for _, s := range msg.Rcpt {
rcpt += s.Address + ";"
}
return fmt.Sprintf("(message-id:%s;from:%s;to:%s)", msg.MessageId, msg.Sender.Address, rcpt)
}
func ParseDomain(addr string) (domain string, err error) {
var parts = strings.Split(addr, "@")
if len(parts) == 0 || len(parts) > 2 {
return "", errors.New("illegal addr " + addr)
}
return parts[1], nil
}
func ParseMessage(recipients []string, sender string, data []byte) (msg Msg, err error) {
msg.Sender, err = ParseAddress(sender)
if err != nil {
return msg, err
}
for _, rcpt := range recipients {
rcptAddr, err := ParseAddress(rcpt)
if err != nil {
return msg, err
}
msg.Rcpt = append(msg.Rcpt, rcptAddr)
}
message, err := mail.ReadMessage(bytes.NewReader(data))
if err != nil {
return msg, err
}
msg.Message = *message
msg.MessageId = msg.Message.Header.Get("message-id")
if msg.MessageId == "" {
id := uuid.NewV4()
uuid.SwitchFormat(uuid.Clean)
msg.MessageId = id.String()
}
msg.RcptDomains = make(map[string]int)
for _, d := range msg.Rcpt {
msg.RcptDomains[d.Domain] = msg.RcptDomains[d.Domain] + 1
}
return msg, nil
}
func ParseAddress(rawAddress string) (address EmailAddress, err error) {
addr, err := mail.ParseAddress(rawAddress)
if err != nil {
return address, err
}
address.RawAddress = rawAddress
address.Address = addr.Address
address.Alias = addr.Name
address.Domain, err = ParseDomain(address.Address)
if err != nil {
return address, err
}
return address, nil
}
func (msg *Msg) GetDomainRecipientList(domain string) (recipients []string) {
for _, rcpt := range msg.Rcpt {
if strings.EqualFold(domain, rcpt.Domain) {
recipients = append(recipients, rcpt.RawAddress)
}
}
return
}