Update copy.go

This commit is contained in:
2026-07-05 13:59:56 +07:00
parent 2bdb4904d6
commit 95ddbf5619
+11 -4
View File
@@ -231,11 +231,18 @@ func streamOne(src, dst *imapclient.Client, dstFolder string, uid imap.UID, flag
}
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
// Append acquires go-imap's per-client encoder mutex and holds it until
// Close() calls enc.end(). Close() MUST run on every path: if io.Copy
// fails mid-write (server stall, idle timeout), returning without Close()
// leaks the mutex and the NEXT Append on this client deadlocks forever on
// beginCommand. Close() is idempotent and always releases the lock.
_, copyErr := io.Copy(appendCmd, bytes.NewReader(body))
closeErr := appendCmd.Close()
if copyErr != nil {
return fmt.Errorf("append body uid %v: %w", uid, copyErr)
}
if err := appendCmd.Close(); err != nil {
return err
if closeErr != nil {
return closeErr
}
_, err := appendCmd.Wait()
return err