util.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package backends
  2. import (
  3. "bytes"
  4. "compress/zlib"
  5. "crypto/md5"
  6. "fmt"
  7. "io"
  8. "net/textproto"
  9. "regexp"
  10. "strings"
  11. )
  12. // First capturing group is header name, second is header value.
  13. // Accounts for folding headers.
  14. var headerRegex, _ = regexp.Compile(`^([\S ]+):([\S ]+(?:\r\n\s[\S ]+)?)`)
  15. // ParseHeaders is deprecated, see mail.Envelope.ParseHeaders instead
  16. func ParseHeaders(mailData string) map[string]string {
  17. var headerSectionEnds int
  18. for i, char := range mailData[:len(mailData)-4] {
  19. if char == '\r' {
  20. if mailData[i+1] == '\n' && mailData[i+2] == '\r' && mailData[i+3] == '\n' {
  21. headerSectionEnds = i + 2
  22. }
  23. }
  24. }
  25. headers := make(map[string]string)
  26. matches := headerRegex.FindAllStringSubmatch(mailData[:headerSectionEnds], -1)
  27. for _, h := range matches {
  28. name := textproto.CanonicalMIMEHeaderKey(strings.TrimSpace(strings.Replace(h[1], "\r\n", "", -1)))
  29. val := strings.TrimSpace(strings.Replace(h[2], "\r\n", "", -1))
  30. headers[name] = val
  31. }
  32. return headers
  33. }
  34. // returns an md5 hash as string of hex characters
  35. func MD5Hex(stringArguments ...string) string {
  36. h := md5.New()
  37. var r *strings.Reader
  38. for i := 0; i < len(stringArguments); i++ {
  39. r = strings.NewReader(stringArguments[i])
  40. _, _ = io.Copy(h, r)
  41. }
  42. sum := h.Sum([]byte{})
  43. return fmt.Sprintf("%x", sum)
  44. }
  45. // concatenate & compress all strings passed in
  46. func Compress(stringArguments ...string) string {
  47. var b bytes.Buffer
  48. var r *strings.Reader
  49. w, _ := zlib.NewWriterLevel(&b, zlib.BestSpeed)
  50. for i := 0; i < len(stringArguments); i++ {
  51. r = strings.NewReader(stringArguments[i])
  52. _, _ = io.Copy(w, r)
  53. }
  54. _ = w.Close()
  55. return b.String()
  56. }