The one from the nhooyr/websocket package seems to work equally well. Signed-off-by: Mihai Parparita <mihai@tailscale.com>main
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