51 lines
1.0 KiB
Go
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
|
|
}
|