diff --git a/client/client.go b/client/client.go index b6abe0f9..fd6af6d4 100644 --- a/client/client.go +++ b/client/client.go @@ -62,7 +62,6 @@ type Client struct { conn *imap.Conn isTLS bool - replies chan []byte loggedOut chan struct{} upgrading bool @@ -184,6 +183,11 @@ func (c *Client) execute(cmdr imap.Commander, h responses.Handler) (*imap.Status cmd := cmdr.Command() cmd.Tag = generateTag() + var replies <-chan []byte + if replier, ok := h.(responses.Replier); ok { + replies = replier.Replies() + } + if c.Timeout > 0 { err := c.conn.SetDeadline(time.Now().Add(c.Timeout)) if err != nil { @@ -255,7 +259,7 @@ func (c *Client) execute(cmdr imap.Commander, h responses.Handler) (*imap.Status for { select { - case reply := <-c.replies: + case reply := <-replies: // Response handler needs to send a reply (Used for AUTHENTICATE) if err := c.writeReply(reply); err != nil { close(unregister) @@ -562,7 +566,6 @@ func New(conn net.Conn) (*Client, error) { c := &Client{ conn: imap.NewConn(conn, r, w), - replies: make(chan []byte), loggedOut: make(chan struct{}), state: imap.ConnectingState, ErrorLog: log.New(os.Stderr, "imap/client: ", log.LstdFlags), diff --git a/client/cmd_noauth.go b/client/cmd_noauth.go index fdad6866..49559092 100644 --- a/client/cmd_noauth.go +++ b/client/cmd_noauth.go @@ -93,10 +93,7 @@ func (c *Client) Authenticate(auth sasl.Client) error { res := &responses.Authenticate{ Mechanism: auth, InitialResponse: ir, - AuthReply: func(reply []byte) error { - c.replies <- reply - return nil - }, + RepliesCh: make(chan []byte, 10), } status, err := c.execute(cmd, res) diff --git a/responses/authenticate.go b/responses/authenticate.go index 0657c84a..8e134cb7 100644 --- a/responses/authenticate.go +++ b/responses/authenticate.go @@ -7,17 +7,21 @@ import ( "github.com/emersion/go-sasl" ) -type AuthReplyFunc func(reply []byte) error - // An AUTHENTICATE response. type Authenticate struct { Mechanism sasl.Client InitialResponse []byte - AuthReply AuthReplyFunc + RepliesCh chan []byte +} + +// Implements +func (r *Authenticate) Replies() <-chan []byte { + return r.RepliesCh } func (r *Authenticate) writeLine(l string) error { - return r.AuthReply([]byte(l + "\r\n")) + r.RepliesCh <- []byte(l + "\r\n") + return nil } func (r *Authenticate) cancel() error { diff --git a/responses/responses.go b/responses/responses.go index 2c1b34bc..4d035eed 100644 --- a/responses/responses.go +++ b/responses/responses.go @@ -26,3 +26,10 @@ type HandlerFunc func(resp imap.Resp) error func (f HandlerFunc) Handle(resp imap.Resp) error { return f(resp) } + +// Replier is a Handler that needs to send raw data (for instance +// AUTHENTICATE). +type Replier interface { + Handler + Replies() <-chan []byte +}