http, crypto/tls: fix read timeouts and closing.

tls.Conn.Close() didn't close the underlying connection and tried to
do a handshake in order to send the close notify alert.

http didn't look for errors from the TLS handshake.

Fixes #2281.

R=bradfitz
CC=golang-dev
https://golang.org/cl/5283045
This commit is contained in:
Adam Langley 2011-10-18 12:59:32 -04:00
parent 0fef8ff181
commit dcbc7ee6c7

20
conn.go
View File

@ -658,7 +658,9 @@ func (c *Conn) readHandshake() (interface{}, os.Error) {
if c.err != nil { if c.err != nil {
return nil, c.err return nil, c.err
} }
c.readRecord(recordTypeHandshake) if err := c.readRecord(recordTypeHandshake); err != nil {
return nil, err
}
} }
data := c.hand.Bytes() data := c.hand.Bytes()
@ -671,7 +673,9 @@ func (c *Conn) readHandshake() (interface{}, os.Error) {
if c.err != nil { if c.err != nil {
return nil, c.err return nil, c.err
} }
c.readRecord(recordTypeHandshake) if err := c.readRecord(recordTypeHandshake); err != nil {
return nil, err
}
} }
data = c.hand.Next(4 + n) data = c.hand.Next(4 + n)
var m handshakeMessage var m handshakeMessage
@ -762,10 +766,18 @@ func (c *Conn) Read(b []byte) (n int, err os.Error) {
// Close closes the connection. // Close closes the connection.
func (c *Conn) Close() os.Error { func (c *Conn) Close() os.Error {
if err := c.Handshake(); err != nil { var alertErr os.Error
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
if c.handshakeComplete {
alertErr = c.sendAlert(alertCloseNotify)
}
if err := c.conn.Close(); err != nil {
return err return err
} }
return c.sendAlert(alertCloseNotify) return alertErr
} }
// Handshake runs the client or server handshake // Handshake runs the client or server handshake