go-message: Understand non-compliant Date headers v1 PROPOSED

Ben Burwell: 1
 Understand non-compliant Date headers

 2 files changed, 27 insertions(+), 1 deletions(-)
Ah, good catch about the header comment!

If this is being fixed upstream, I suppose it does not make sense to
patch it in go-message. Though, it doesn't look like that CL has been
applied yet and since go 1.13 is frozen we won't see it until at least
February 2020 with 1.14. In the meantime, I have a few broken messages
in aerc, so I'm not quite sure what to do about that. Doesn't seem like
this is affecting too many people based on the activity on that github
issue, so maybe I'll just keep it patched locally until go is fixed.






Alright, I think I will take a stab at a patch for that, then. Disregard
this one :)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~emersion/public-inbox/patches/7188/mbox | git am -3
Learn more about email & git

[PATCH go-message] Understand non-compliant Date headers Export this patch

Extend the net/mail date parsing with additional non-conforming formats
which appear in the wild.
 mail/header.go      | 16 +++++++++++++++-
 mail/header_test.go | 12 ++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/mail/header.go b/mail/header.go
index 22c3a01..4355e13 100644
--- a/mail/header.go
+++ b/mail/header.go
@@ -31,7 +31,21 @@ func (h *Header) SetAddressList(key string, addrs []*Address) {

// Date parses the Date header field.
func (h *Header) Date() (time.Time, error) {
	return mail.ParseDate(h.Get("Date"))
	text := h.Get("Date")
	t, parseErr := mail.ParseDate(text)
	if parseErr == nil {
		return t, nil
	layouts := []string{
		// X-Mailer: EarthLink Zoo Mail 1.0
		"Mon, _2 Jan 2006 15:04:05 -0700 (GMT-07:00)",
	for _, layout := range layouts {
		if t, err := time.Parse(layout, text); err == nil {
			return t, nil
	return time.Time{}, parseErr

// SetDate formats the Date header field.
diff --git a/mail/header_test.go b/mail/header_test.go
index db4cf4e..32149b1 100644
--- a/mail/header_test.go
+++ b/mail/header_test.go
@@ -42,3 +42,15 @@ func TestHeader(t *testing.T) {
		t.Errorf("Expected header subject to be %v, but got %v", subject, got)

func TestDateAlternateFormat(t *testing.T) {
	var h mail.Header
	h.Set("Date", "Tue, 01 Feb 2019 12:35:01 -0400 (GMT-04:00)")
	actual, err := h.Date()
	if err != nil {
		t.Fatalf("Expected no error but got: %v", err)
	if !actual.Equal(time.Unix(1549038901, 0)) {
		t.Errorf("unexpected time: %v", actual)
Seems to me like this is a header field comment (so there could be
anything inside the parentheses).

See [1] for the definition of CFWS and [2] for the definition of
date-time inside Date header fields:

    date-time       =   [ day-of-week "," ] date time [CFWS]

Note the trailing CFWS.

It seems like there is already a Go patch for this [3].

[1]: https://tools.ietf.org/html/rfc5322#section-3.2.2
[2]: https://tools.ietf.org/html/rfc5322#section-3.3
[3]: https://go-review.googlesource.com/c/go/+/117596/
View this thread in the archives