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.
This commit is contained in:
Yawning Angel 2015-03-22 04:21:23 +00:00
parent b19f84d674
commit 8736a9cd73
3 changed files with 12 additions and 2 deletions

View File

@ -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")
}

View File

@ -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
}

View File

@ -32,6 +32,7 @@ type Conn struct {
conn *textproto.Conn
isAuthenticated bool
debugLog bool
cachedPI *ProtocolInfo
asyncReaderLock sync.Mutex
asyncReaderRunning bool