From 8736a9cd73e612642ebd4129cdfc5b931443c4c4 Mon Sep 17 00:00:00 2001 From: Yawning Angel Date: Sun, 22 Mar 2015 04:21:23 +0000 Subject: [PATCH] Cache the PROTOCOLINFO response if it was issued before AUTHENTICATE. Control clients get one PROTOCOLINFO before they must issue an AUTHCHALLENGE or AUTHENTICATE, and the Authenticate() implementation uses PROTOCOLINFO. This allows users to call ProtocolInfo() before Authenticate() without mysterious failures. --- cmd_authenticate.go | 3 +-- cmd_protocolinfo.go | 10 ++++++++++ conn.go | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd_authenticate.go b/cmd_authenticate.go index d2b485f..aba7bd6 100644 --- a/cmd_authenticate.go +++ b/cmd_authenticate.go @@ -132,7 +132,6 @@ func (c *Conn) Authenticate(password string) error { _, err = c.Request("%s %s", cmdAuthenticate, passwordStr) c.isAuthenticated = err == nil return err - } else { - return newProtocolError("no supported authentication methods") } + return newProtocolError("no supported authentication methods") } diff --git a/cmd_protocolinfo.go b/cmd_protocolinfo.go index 133771a..d05da6d 100644 --- a/cmd_protocolinfo.go +++ b/cmd_protocolinfo.go @@ -23,6 +23,13 @@ type ProtocolInfo struct { // ProtocolInfo issues a PROTOCOLINFO command and returns the parsed response. func (c *Conn) ProtocolInfo() (*ProtocolInfo, error) { + // In the pre-authentication state, only one PROTOCOLINFO command + // may be issued. Cache the value returned so that subsequent + // calls continue to work. + if !c.isAuthenticated && c.cachedPI != nil { + return c.cachedPI, nil + } + resp, err := c.Request("PROTOCOLINFO") if err != nil { return nil, err @@ -79,5 +86,8 @@ func (c *Conn) ProtocolInfo() (*ProtocolInfo, error) { default: // MUST ignore unsupported InfoLines. } } + if !c.isAuthenticated { + c.cachedPI = pi + } return pi, nil } diff --git a/conn.go b/conn.go index e354ba0..4e8d8cd 100644 --- a/conn.go +++ b/conn.go @@ -32,6 +32,7 @@ type Conn struct { conn *textproto.Conn isAuthenticated bool debugLog bool + cachedPI *ProtocolInfo asyncReaderLock sync.Mutex asyncReaderRunning bool