mirror of https://github.com/tailscale/tailscale/
net/wsconn: remove homegrown wrapper for turning a websocket.Conn into a net.Conn
The one from the nhooyr/websocket package seems to work equally well. Signed-off-by: Mihai Parparita <mihai@tailscale.com>pull/4323/head
parent
cfb5bd0559
commit
edc90ebc61
@ -1,104 +0,0 @@
|
|||||||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package wsconn contains an adapter type that turns
|
|
||||||
// a websocket connection into a net.Conn.
|
|
||||||
package wsconn
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"nhooyr.io/websocket"
|
|
||||||
)
|
|
||||||
|
|
||||||
// New returns a net.Conn wrapper around c,
|
|
||||||
// using c to send and receive binary messages with
|
|
||||||
// chunks of bytes with no defined framing, effectively
|
|
||||||
// discarding all WebSocket-level message framing.
|
|
||||||
func New(c *websocket.Conn) net.Conn {
|
|
||||||
return &websocketConn{c: c}
|
|
||||||
}
|
|
||||||
|
|
||||||
// websocketConn implements net.Conn around a *websocket.Conn,
|
|
||||||
// treating a websocket.Conn as a byte stream, ignoring the WebSocket
|
|
||||||
// frame/message boundaries.
|
|
||||||
type websocketConn struct {
|
|
||||||
c *websocket.Conn
|
|
||||||
|
|
||||||
// rextra are extra bytes owned by the reader.
|
|
||||||
rextra []byte
|
|
||||||
|
|
||||||
mu sync.Mutex
|
|
||||||
rdeadline time.Time
|
|
||||||
cancelRead context.CancelFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wc *websocketConn) LocalAddr() net.Addr { return addr{} }
|
|
||||||
func (wc *websocketConn) RemoteAddr() net.Addr { return addr{} }
|
|
||||||
|
|
||||||
type addr struct{}
|
|
||||||
|
|
||||||
func (addr) Network() string { return "websocket" }
|
|
||||||
func (addr) String() string { return "websocket" }
|
|
||||||
|
|
||||||
func (wc *websocketConn) Read(p []byte) (n int, err error) {
|
|
||||||
// Drain any leftover from previously.
|
|
||||||
n = copy(p, wc.rextra)
|
|
||||||
if n > 0 {
|
|
||||||
wc.rextra = wc.rextra[n:]
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var ctx context.Context
|
|
||||||
var cancel context.CancelFunc
|
|
||||||
|
|
||||||
wc.mu.Lock()
|
|
||||||
if dl := wc.rdeadline; !dl.IsZero() {
|
|
||||||
ctx, cancel = context.WithDeadline(context.Background(), wc.rdeadline)
|
|
||||||
} else {
|
|
||||||
ctx, cancel = context.WithDeadline(context.Background(), time.Now().Add(30*24*time.Hour))
|
|
||||||
wc.rdeadline = time.Time{}
|
|
||||||
}
|
|
||||||
wc.cancelRead = cancel
|
|
||||||
wc.mu.Unlock()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
_, buf, err := wc.c.Read(ctx)
|
|
||||||
n = copy(p, buf)
|
|
||||||
wc.rextra = buf[n:]
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wc *websocketConn) Write(p []byte) (n int, err error) {
|
|
||||||
err = wc.c.Write(context.Background(), websocket.MessageBinary, p)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wc *websocketConn) Close() error { return wc.c.Close(websocket.StatusNormalClosure, "close") }
|
|
||||||
|
|
||||||
func (wc *websocketConn) SetDeadline(t time.Time) error {
|
|
||||||
wc.SetReadDeadline(t)
|
|
||||||
wc.SetWriteDeadline(t)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wc *websocketConn) SetReadDeadline(t time.Time) error {
|
|
||||||
wc.mu.Lock()
|
|
||||||
defer wc.mu.Unlock()
|
|
||||||
if !t.IsZero() && (wc.rdeadline.IsZero() || t.Before(wc.rdeadline)) && wc.cancelRead != nil {
|
|
||||||
wc.cancelRead()
|
|
||||||
}
|
|
||||||
wc.rdeadline = t
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wc *websocketConn) SetWriteDeadline(t time.Time) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
Reference in New Issue