Implement net.Conn for websocketconn.Conn.

We had already implemented Read, Write, and Close. Pass RemoteAddr,
LocalAddr, SetReadDeadline, and SetWriteDeadline through to the
underlying *websocket.Conn. Implement SetDeadline by calling both
SetReadDeadline and SetWriteDeadline.

https://bugs.torproject.org/33144
This commit is contained in:
David Fifield 2020-02-03 13:22:03 -07:00
parent 01e28aa460
commit 256959ca65

View file

@ -7,29 +7,36 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
// An abstraction that makes an underlying WebSocket connection look like an // An abstraction that makes an underlying WebSocket connection look like a
// io.ReadWriteCloser. // net.Conn.
type Conn struct { type Conn struct {
ws *websocket.Conn *websocket.Conn
Reader io.Reader Reader io.Reader
Writer io.Writer Writer io.Writer
} }
// Implements io.Reader.
func (conn *Conn) Read(b []byte) (n int, err error) { func (conn *Conn) Read(b []byte) (n int, err error) {
return conn.Reader.Read(b) return conn.Reader.Read(b)
} }
// Implements io.Writer.
func (conn *Conn) Write(b []byte) (n int, err error) { func (conn *Conn) Write(b []byte) (n int, err error) {
return conn.Writer.Write(b) return conn.Writer.Write(b)
} }
// Implements io.Closer.
func (conn *Conn) Close() error { func (conn *Conn) Close() error {
// Ignore any error in trying to write a Close frame. // Ignore any error in trying to write a Close frame.
_ = conn.ws.WriteControl(websocket.CloseMessage, []byte{}, time.Now().Add(time.Second)) _ = conn.Conn.WriteControl(websocket.CloseMessage, []byte{}, time.Now().Add(time.Second))
return conn.ws.Close() return conn.Conn.Close()
}
func (conn *Conn) SetDeadline(t time.Time) error {
errRead := conn.Conn.SetReadDeadline(t)
errWrite := conn.Conn.SetWriteDeadline(t)
err := errRead
if err == nil {
err = errWrite
}
return err
} }
func readLoop(w io.Writer, ws *websocket.Conn) error { func readLoop(w io.Writer, ws *websocket.Conn) error {
@ -105,7 +112,7 @@ func New(ws *websocket.Conn) *Conn {
pr2.CloseWithError(closeErrorToEOF(writeLoop(ws, pr2))) pr2.CloseWithError(closeErrorToEOF(writeLoop(ws, pr2)))
}() }()
return &Conn{ return &Conn{
ws: ws, Conn: ws,
Reader: pr1, Reader: pr1,
Writer: pw2, Writer: pw2,
} }