[PATCH] Add utility function for generating Message-Id
Export this patch
---
go.mod | 1 +
go.sum | 7 +++++++
mail/mail.go | 31 +++++++++++++++++++++++++++++++
mail/mail_test.go | 15 +++++++++++++++
4 files changed, 54 insertions(+)
create mode 100644 go.sum
diff --git a/go.mod b/go.mod
index c4b1a3e..d077adc 100644
--- a/go.mod
+++ b/go.mod
@@ -4,5 +4,6 @@ go 1.12
require (
github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe
+ github.com/martinlindhe/base36 v0.0.0-20190418230009-7c6542dfbb41
golang.org/x/text v0.3.2
)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..93c2bb9
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,7 @@
+ github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe h1:40SWqY0zE3qCi6ZrtTf5OUdNm5lDnGnjRSq9GgmeTrg=
+ github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
+ github.com/martinlindhe/base36 v0.0.0-20190418230009-7c6542dfbb41 h1:CVsnY46BCLkX9XOhALJ/S7yb9ayc4eqjXSXO3tyB66A=
+ github.com/martinlindhe/base36 v0.0.0-20190418230009-7c6542dfbb41/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8=
+ golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/mail/mail.go b/mail/mail.go
index 2f9a12c..68ae121 100644
--- a/mail/mail.go
+++ b/mail/mail.go
@@ -7,3 +7,34 @@
//
// RFC 5322 defines the Internet Message Format.
package mail
+
+ import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "math/rand"
+ "os"
+ "time"
+
+ "github.com/martinlindhe/base36"
+ )
+
+ // Generates an RFC 2822-complaint Message-Id based on the informational draft
If you have an RFC complaint, I suggest you let them know at [1]. :)
[1]: https://www.rfc-editor.org/errata.php
+ // "Recommendations for generating Message IDs", for lack of a better
+ // authoritative source.
+ func GenerateMessageId() string {
Nit: s/Id/ID/
See https://github.com/golang/go/wiki/CodeReviewComments#initialisms
+ var (
+ now bytes.Buffer
+ nonce bytes.Buffer
+ )
+ binary.Write(&now, binary.BigEndian, time.Now().UnixNano())
+ binary.Write(&nonce, binary.BigEndian, rand.Uint64())
This is math/rand, so this will always produce the same series of values for
each execution.
I guess using crypto/rand would be easiest, and would also make IDs less
predictable.
+ hostname, err := os.Hostname()
I wonder if we should allow callers to override this. (Well, /shrug, if they
don't like it they can always roll their own)
+ if err != nil {
+ hostname = "localhost"
+ }
+ return fmt.Sprintf("<%s.%s@%s>",
+ base36.EncodeBytes(now.Bytes()),
+ base36.EncodeBytes(nonce.Bytes()),
+ hostname)
+ }
diff --git a/mail/mail_test.go b/mail/mail_test.go
index cfb30ca..5f8c713 100644
--- a/mail/mail_test.go
+++ b/mail/mail_test.go
@@ -1,5 +1,12 @@
package mail_test
+ import (
+ "regexp"
+ "testing"
+
+ "github.com/emersion/go-message/mail"
+ )
+
const mailString = "Subject: Your Name\r\n" +
"Content-Type: multipart/mixed; boundary=message-boundary\r\n" +
"\r\n" +
@@ -33,3 +40,11 @@ const nestedMailString = "Subject: Fwd: Your Name\r\n" +
"\r\n" +
mailString +
"--outer-message-boundary--\r\n"
+
+ func TestGenerateMessageId(t *testing.T) {
+ msgId := mail.GenerateMessageId()
+ regex := regexp.MustCompile(`^<.*@.*>$`)
+ if !regex.MatchString(msgId) {
+ t.Error("Generated message ID does not meet RFC requirement")
+ }
+ }
--
2.21.0