Skip to content

Commit 7f7f4e6

Browse files
committed
just small optimizations:
- regexes are compiled once - md5 hashing & compressing functions use less memory (data is streamed into buffers) - avoid string concatenation when passing to the hashing & compressing functions - pass strings by reference to md5 & compress functions
1 parent e85eb42 commit 7f7f4e6

File tree

2 files changed

+40
-22
lines changed

2 files changed

+40
-22
lines changed

save_mail.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,13 @@ func saveMail() {
6565
to = user + "@" + mainConfig.Primary_host
6666
}
6767
length = len(payload.client.data)
68+
ts := strconv.FormatInt(time.Now().UnixNano(), 10);
6869
payload.client.subject = mimeHeaderDecode(payload.client.subject)
69-
payload.client.hash = md5hex(to + payload.client.mail_from + payload.client.subject + strconv.FormatInt(time.Now().UnixNano(), 10))
70+
payload.client.hash = md5hex(
71+
&to,
72+
&payload.client.mail_from,
73+
&payload.client.subject,
74+
&ts)
7075
// Add extra headers
7176
add_head := ""
7277
add_head += "Delivered-To: " + to + "\r\n"
@@ -75,7 +80,7 @@ func saveMail() {
7580
payload.server.Config.Host_name + ";\r\n"
7681
add_head += " " + time.Now().Format(time.RFC1123Z) + "\r\n"
7782
// compress to save space
78-
payload.client.data = compress(add_head + payload.client.data)
83+
payload.client.data = compress(&add_head, &payload.client.data)
7984
body = "gzencode"
8085
redis_err = redisClient.redisConnection()
8186
if redis_err == nil {

util.go

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import (
55
"compress/zlib"
66
"crypto/md5"
77
"encoding/base64"
8-
"encoding/hex"
98
"errors"
109
"github.com/sloonz/go-qprintable"
1110
"gopkg.in/iconv.v1"
1211
"io/ioutil"
1312
"regexp"
1413
"strings"
14+
"io"
15+
"fmt"
1516
)
1617

1718
func validateEmailData(client *Client) (user string, host string, addr_err error) {
@@ -30,9 +31,10 @@ func validateEmailData(client *Client) (user string, host string, addr_err error
3031
return user, host, addr_err
3132
}
3233

34+
var extractEmailRegex, _ = regexp.Compile(`<(.+?)@(.+?)>`) // go home regex, you're drunk!
35+
3336
func extractEmail(str string) (name string, host string, err error) {
34-
re, _ := regexp.Compile(`<(.+?)@(.+?)>`) // go home regex, you're drunk!
35-
if matched := re.FindStringSubmatch(str); len(matched) > 2 {
37+
if matched := extractEmailRegex.FindStringSubmatch(str); len(matched) > 2 {
3638
host = validHost(matched[2])
3739
name = matched[1]
3840
} else {
@@ -46,12 +48,12 @@ func extractEmail(str string) (name string, host string, err error) {
4648
}
4749
return name, host, err
4850
}
49-
51+
var mimeRegex, _ = regexp.Compile(`=\?(.+?)\?([QBqp])\?(.+?)\?=`)
5052
// Decode strings in Mime header format
5153
// eg. =?ISO-2022-JP?B?GyRCIVo9dztSOWJAOCVBJWMbKEI=?=
5254
func mimeHeaderDecode(str string) string {
53-
reg, _ := regexp.Compile(`=\?(.+?)\?([QBqp])\?(.+?)\?=`)
54-
matched := reg.FindAllStringSubmatch(str, -1)
55+
56+
matched := mimeRegex.FindAllStringSubmatch(str, -1)
5557
var charset, encoding, payload string
5658
if matched != nil {
5759
for i := 0; i < len(matched); i++ {
@@ -79,10 +81,10 @@ func mimeHeaderDecode(str string) string {
7981
return str
8082
}
8183

84+
var valihostRegex, _ = regexp.Compile(`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$`)
8285
func validHost(host string) string {
8386
host = strings.Trim(host, " ")
84-
re, _ := regexp.Compile(`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$`)
85-
if re.MatchString(host) {
87+
if valihostRegex.MatchString(host) {
8688
return host
8789
}
8890
return ""
@@ -133,17 +135,10 @@ func fromQuotedP(data string) string {
133135
return string(res)
134136
}
135137

136-
func compress(s string) string {
137-
var b bytes.Buffer
138-
w, _ := zlib.NewWriterLevel(&b, zlib.BestSpeed) // flate.BestCompression
139-
w.Write([]byte(s))
140-
w.Close()
141-
return b.String()
142-
}
143138

139+
var charsetRegex, _ = regexp.Compile(`[_:.\/\\]`)
144140
func fixCharset(charset string) string {
145-
reg, _ := regexp.Compile(`[_:.\/\\]`)
146-
fixed_charset := reg.ReplaceAllString(charset, "-")
141+
fixed_charset := charsetRegex.ReplaceAllString(charset, "-")
147142
// Fix charset
148143
// borrowed from http://squirrelmail.svn.sourceforge.net/viewvc/squirrelmail/trunk/squirrelmail/include/languages.php?revision=13765&view=markup
149144
// OE ks_c_5601_1987 > cp949
@@ -164,9 +159,27 @@ func fixCharset(charset string) string {
164159
return charset
165160
}
166161

167-
func md5hex(str string) string {
162+
// returns an md5 hash as string of hex characters
163+
func md5hex(stringArguments ...*string) string {
168164
h := md5.New()
169-
h.Write([]byte(str))
165+
var r *strings.Reader
166+
for i:=0; i < len(stringArguments); i++ {
167+
r = strings.NewReader(*stringArguments[i])
168+
io.Copy(h, r)
169+
}
170170
sum := h.Sum([]byte{})
171-
return hex.EncodeToString(sum)
171+
return fmt.Sprintf("%x", sum)
172+
}
173+
174+
// concatenate & compress all strings passed in
175+
func compress(stringArguments ...*string) string {
176+
var b bytes.Buffer
177+
var r *strings.Reader
178+
w, _ := zlib.NewWriterLevel(&b, zlib.BestSpeed)
179+
for i:=0; i < len(stringArguments); i++ {
180+
r = strings.NewReader(*stringArguments[i])
181+
io.Copy(w, r)
182+
}
183+
w.Close()
184+
return b.String()
172185
}

0 commit comments

Comments
 (0)