when cleaning up messages in rejects mailbox, remove the on-disk message file too

we were leaving files behind
This commit is contained in:
Mechiel Lukkien 2023-02-13 11:06:16 +01:00
parent 707d3a3fa0
commit 2601766c2f
No known key found for this signature in database
2 changed files with 36 additions and 8 deletions

View file

@ -2231,7 +2231,9 @@ func (c *conn) deliver(ctx context.Context, recvHdrFor func(string) string, msgW
conf, _ := acc.Conf() conf, _ := acc.Conf()
if conf.RejectsMailbox != "" && messageID != "" { if conf.RejectsMailbox != "" && messageID != "" {
acc.RejectsRemove(log, conf.RejectsMailbox, messageID) if err := acc.RejectsRemove(log, conf.RejectsMailbox, messageID); err != nil {
log.Errorx("removing message from rejects mailbox", err, mlog.Field("messageID", messageID))
}
} }
}) })

View file

@ -1030,6 +1030,16 @@ func (a *Account) DeliverMailbox(log *mlog.Log, mailbox string, m *Message, msgF
func (a *Account) TidyRejectsMailbox(log *mlog.Log, rejectsMailbox string) (hasSpace bool, rerr error) { func (a *Account) TidyRejectsMailbox(log *mlog.Log, rejectsMailbox string) (hasSpace bool, rerr error) {
var changes []Change var changes []Change
var remove []Message
defer func() {
for _, m := range remove {
p := a.MessagePath(m.ID)
if err := os.Remove(p); err != nil {
log.Errorx("removing rejects message file", err, mlog.Field("path", p))
}
}
}()
err := extransact(a.DB, true, func(tx *bstore.Tx) error { err := extransact(a.DB, true, func(tx *bstore.Tx) error {
mb := a.MailboxFindX(tx, rejectsMailbox) mb := a.MailboxFindX(tx, rejectsMailbox)
if mb == nil { if mb == nil {
@ -1043,7 +1053,8 @@ func (a *Account) TidyRejectsMailbox(log *mlog.Log, rejectsMailbox string) (hasS
qdel := bstore.QueryTx[Message](tx) qdel := bstore.QueryTx[Message](tx)
qdel.FilterNonzero(Message{MailboxID: mb.ID}) qdel.FilterNonzero(Message{MailboxID: mb.ID})
qdel.FilterLess("Received", old) qdel.FilterLess("Received", old)
remove, err := qdel.List() var err error
remove, err = qdel.List()
xcheckf(err, "listing old messages") xcheckf(err, "listing old messages")
changes = a.xremoveMessages(log, tx, mb, remove) changes = a.xremoveMessages(log, tx, mb, remove)
@ -1058,12 +1069,16 @@ func (a *Account) TidyRejectsMailbox(log *mlog.Log, rejectsMailbox string) (hasS
return nil return nil
}) })
if err != nil {
remove = nil // Don't remove files on failure.
return false, err
}
comm := RegisterComm(a) comm := RegisterComm(a)
defer comm.Unregister() defer comm.Unregister()
comm.Broadcast(changes) comm.Broadcast(changes)
return hasSpace, err return hasSpace, nil
} }
func (a *Account) xremoveMessages(log *mlog.Log, tx *bstore.Tx, mb *Mailbox, l []Message) []Change { func (a *Account) xremoveMessages(log *mlog.Log, tx *bstore.Tx, mb *Mailbox, l []Message) []Change {
@ -1110,17 +1125,25 @@ func (a *Account) xremoveMessages(log *mlog.Log, tx *bstore.Tx, mb *Mailbox, l [
// RejectsRemove removes a message from the rejects mailbox if present. // RejectsRemove removes a message from the rejects mailbox if present.
// Caller most hold account wlock. // Caller most hold account wlock.
// Changes are broadcasted. // Changes are broadcasted.
func (a *Account) RejectsRemove(log *mlog.Log, rejectsMailbox, messageID string) { func (a *Account) RejectsRemove(log *mlog.Log, rejectsMailbox, messageID string) error {
var changes []Change var changes []Change
var remove []Message
defer func() {
for _, m := range remove {
p := a.MessagePath(m.ID)
if err := os.Remove(p); err != nil {
log.Errorx("removing rejects message file", err, mlog.Field("path", p))
}
}
}()
err := extransact(a.DB, true, func(tx *bstore.Tx) error { err := extransact(a.DB, true, func(tx *bstore.Tx) error {
mb := a.MailboxFindX(tx, rejectsMailbox) mb := a.MailboxFindX(tx, rejectsMailbox)
if mb == nil { if mb == nil {
return nil return nil
} }
// Note: these cannot have Recipients.
var remove []Message
q := bstore.QueryTx[Message](tx) q := bstore.QueryTx[Message](tx)
q.FilterNonzero(Message{MailboxID: mb.ID, MessageID: messageID}) q.FilterNonzero(Message{MailboxID: mb.ID, MessageID: messageID})
remove, err := q.List() remove, err := q.List()
@ -1128,15 +1151,18 @@ func (a *Account) RejectsRemove(log *mlog.Log, rejectsMailbox, messageID string)
changes = a.xremoveMessages(log, tx, mb, remove) changes = a.xremoveMessages(log, tx, mb, remove)
return err return nil
}) })
if err != nil { if err != nil {
log.Errorx("removing message from rejects mailbox", err, mlog.Field("account", a.Name), mlog.Field("rejectsMailbox", rejectsMailbox), mlog.Field("messageID", messageID)) remove = nil // Don't remove files on failure.
return err
} }
comm := RegisterComm(a) comm := RegisterComm(a)
defer comm.Unregister() defer comm.Unregister()
comm.Broadcast(changes) comm.Broadcast(changes)
return nil
} }
// We keep a cache of recent successful authentications, so we don't have to bcrypt successful calls each time. // We keep a cache of recent successful authentications, so we don't have to bcrypt successful calls each time.