Handle net.Error Temporary() deprecation

See https://go.dev/issue/45729.

- Remove hideTempError

  The hideTempError function was used to prevent connection methods from
  returning a net.Error with Temporary() == true.

  Connection methods do not support retry after returning any net.Error,
  including errors with Temporary() == true.

  Presumably hideTempError was used to prevent applications from
  futilely retrying connection method calls on temporary errors.

  The hideTempError function is not needed now that net.Error
  Temporary() is deprecated.

- Remove use of the deprecated net.Error Temporary() method in the
  default ping handler by ignoring all errors returned from
  WriteControl. Ignoring errors allows the application to continue
  reading messages after a write error and is consistent with how the
  default close handler calls WriteControl.
This commit is contained in:
tebuka 2024-06-11 08:08:32 -07:00 committed by Daniel Holmes
parent 682b25fffc
commit a62d9d2a84
1 changed files with 6 additions and 18 deletions

22
conn.go
View File

@ -192,13 +192,6 @@ func newMaskKey() [4]byte {
return k return k
} }
func hideTempErr(err error) error {
if e, ok := err.(net.Error); ok && e.Temporary() {
err = &netError{msg: e.Error(), timeout: e.Timeout()}
}
return err
}
func isControl(frameType int) bool { func isControl(frameType int) bool {
return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage
} }
@ -364,7 +357,6 @@ func (c *Conn) RemoteAddr() net.Addr {
// Write methods // Write methods
func (c *Conn) writeFatal(err error) error { func (c *Conn) writeFatal(err error) error {
err = hideTempErr(err)
c.writeErrMu.Lock() c.writeErrMu.Lock()
if c.writeErr == nil { if c.writeErr == nil {
c.writeErr = err c.writeErr = err
@ -1014,7 +1006,7 @@ func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
for c.readErr == nil { for c.readErr == nil {
frameType, err := c.advanceFrame() frameType, err := c.advanceFrame()
if err != nil { if err != nil {
c.readErr = hideTempErr(err) c.readErr = err
break break
} }
@ -1054,7 +1046,7 @@ func (r *messageReader) Read(b []byte) (int, error) {
b = b[:c.readRemaining] b = b[:c.readRemaining]
} }
n, err := c.br.Read(b) n, err := c.br.Read(b)
c.readErr = hideTempErr(err) c.readErr = err
if c.isServer { if c.isServer {
c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n]) c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])
} }
@ -1075,7 +1067,7 @@ func (r *messageReader) Read(b []byte) (int, error) {
frameType, err := c.advanceFrame() frameType, err := c.advanceFrame()
switch { switch {
case err != nil: case err != nil:
c.readErr = hideTempErr(err) c.readErr = err
case frameType == TextMessage || frameType == BinaryMessage: case frameType == TextMessage || frameType == BinaryMessage:
c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader") c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
} }
@ -1164,13 +1156,9 @@ func (c *Conn) PingHandler() func(appData string) error {
func (c *Conn) SetPingHandler(h func(appData string) error) { func (c *Conn) SetPingHandler(h func(appData string) error) {
if h == nil { if h == nil {
h = func(message string) error { h = func(message string) error {
err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) // Make a best effort to send the pong mesage.
if err == ErrCloseSent { _ = c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
return nil return nil
} else if e, ok := err.(net.Error); ok && e.Temporary() {
return nil
}
return err
} }
} }
c.handlePing = h c.handlePing = h