fix(imapx): preserve source internal date on APPEND

This commit is contained in:
2026-07-01 17:57:12 +07:00
parent 06c0598b80
commit a54ec1d148
2 changed files with 133 additions and 4 deletions
+5 -4
View File
@@ -5,6 +5,7 @@ import (
"context"
"fmt"
"io"
"time"
"github.com/emersion/go-imap/v2"
"github.com/emersion/go-imap/v2/imapclient"
@@ -48,7 +49,7 @@ func CopyFolder(ctx context.Context, src, dst *imapclient.Client, srcFolder, dst
// 1) Collect envelope+uid+size for every message (cheap pass, no bodies).
metaSet := imap.SeqSet{imap.SeqRange{Start: 1, Stop: sel.NumMessages}}
metas, err := src.Fetch(metaSet, &imap.FetchOptions{
UID: true, Envelope: true, RFC822Size: true, Flags: true,
UID: true, Envelope: true, RFC822Size: true, Flags: true, InternalDate: true,
}).Collect()
if err != nil {
return res, fmt.Errorf("fetch meta: %w", err)
@@ -75,7 +76,7 @@ func CopyFolder(ctx context.Context, src, dst *imapclient.Client, srcFolder, dst
}
continue
}
if err := streamOne(src, dst, dstFolder, m.UID, m.Flags); err != nil {
if err := streamOne(src, dst, dstFolder, m.UID, m.Flags, m.InternalDate); err != nil {
res.Errors++
continue
}
@@ -94,7 +95,7 @@ func CopyFolder(ctx context.Context, src, dst *imapclient.Client, srcFolder, dst
// streamOne FETCHes BODY[] for one message and APPENDs it into dst without
// spooling to disk. The body is buffered in RAM only for the duration of
// this single FETCH->APPEND round trip.
func streamOne(src, dst *imapclient.Client, dstFolder string, uid imap.UID, flags []imap.Flag) error {
func streamOne(src, dst *imapclient.Client, dstFolder string, uid imap.UID, flags []imap.Flag, internalDate time.Time) error {
bodySection := &imap.FetchItemBodySection{}
fetchCmd := src.Fetch(imap.UIDSetNum(uid), &imap.FetchOptions{
BodySection: []*imap.FetchItemBodySection{bodySection},
@@ -126,7 +127,7 @@ func streamOne(src, dst *imapclient.Client, dstFolder string, uid imap.UID, flag
return fmt.Errorf("empty body uid %v", uid)
}
appendCmd := dst.Append(dstFolder, int64(len(body)), &imap.AppendOptions{Flags: keepFlags(flags)})
appendCmd := dst.Append(dstFolder, int64(len(body)), &imap.AppendOptions{Flags: keepFlags(flags), Time: internalDate})
if _, err := io.Copy(appendCmd, bytes.NewReader(body)); err != nil {
return err
}