Files
go-imap/imapserver/idle.go
2025-12-08 06:42:29 +02:00

51 lines
1.0 KiB
Go

package imapserver
import (
"fmt"
"io"
"runtime/debug"
"github.com/emersion/go-imap/v2"
"github.com/emersion/go-imap/v2/internal/imapwire"
)
func (c *Conn) handleIdle(dec *imapwire.Decoder) error {
if !dec.ExpectCRLF() {
return dec.Err()
}
if err := c.checkState(imap.ConnStateAuthenticated); err != nil {
return err
}
if err := c.writeContReq("idling"); err != nil {
return err
}
stop := make(chan struct{})
done := make(chan error, 1)
go func() {
defer func() {
if v := recover(); v != nil {
c.server.logger().Printf("panic idling: %v\n%s", v, debug.Stack())
done <- fmt.Errorf("imapserver: panic idling")
}
}()
w := &UpdateWriter{conn: c, allowExpunge: true}
done <- c.session.Idle(w, stop)
}()
c.setReadTimeout(idleReadTimeout)
line, isPrefix, err := c.br.ReadLine()
close(stop)
if err == io.EOF {
return nil
} else if err != nil {
return err
} else if isPrefix || string(line) != "DONE" {
return newClientBugError("Syntax error: expected DONE to end IDLE command")
}
return <-done
}