From 65a6800411f4cde625d47332c6a53ce487d43f7f Mon Sep 17 00:00:00 2001 From: Jacalz Date: Mon, 7 Jul 2025 20:10:03 +0200 Subject: [PATCH 1/5] Use any instead of interface{} given Go > 1.18 --- README.md | 2 +- autobahn_test.go | 4 ++-- conn_test.go | 6 +++--- example_test.go | 2 +- internal/errd/wrap.go | 2 +- internal/examples/chat/chat.go | 2 +- internal/examples/echo/server.go | 2 +- internal/test/assert/assert.go | 4 ++-- internal/thirdparty/gin_test.go | 2 +- internal/wsjs/wsjs_js.go | 8 ++++---- wsjson/wsjson.go | 8 ++++---- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 80d2b3cc..6e986897 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() - var v interface{} + var v any err = wsjson.Read(ctx, c, &v) if err != nil { // ... diff --git a/autobahn_test.go b/autobahn_test.go index cd0cc9bb..e43851c8 100644 --- a/autobahn_test.go +++ b/autobahn_test.go @@ -130,7 +130,7 @@ func wstestServer(tb testing.TB, ctx context.Context) (url string, closeFn func( url = "ws://" + serverAddr const outDir = "ci/out/autobahn-report" - specFile, err := tempJSONFile(map[string]interface{}{ + specFile, err := tempJSONFile(map[string]any{ "url": url, "outdir": outDir, "cases": autobahnCases, @@ -280,7 +280,7 @@ func unusedListenAddr() (_ string, err error) { return l.Addr().String(), nil } -func tempJSONFile(v interface{}) (string, error) { +func tempJSONFile(v any) (string, error) { f, err := os.CreateTemp("", "temp.json") if err != nil { return "", fmt.Errorf("temp file: %w", err) diff --git a/conn_test.go b/conn_test.go index 45bb75be..af3d973b 100644 --- a/conn_test.go +++ b/conn_test.go @@ -341,7 +341,7 @@ func TestConn(t *testing.T) { return wsjson.Write(tt.ctx, c1, exp) }) - var act interface{} + var act any err := wsjson.Read(tt.ctx, c1, &act) assert.Success(t, err) assert.Equal(t, "read msg", exp, act) @@ -372,7 +372,7 @@ func TestConn(t *testing.T) { return wsjson.Write(tt.ctx, c1, exp) }) - var act interface{} + var act any err := wsjson.Read(tt.ctx, c1, &act) assert.Success(t, err) assert.Equal(t, "read msg", exp, act) @@ -660,7 +660,7 @@ func assertEcho(tb testing.TB, ctx context.Context, c *websocket.Conn) { return wsjson.Write(ctx, c, exp) }) - var act interface{} + var act any c.SetReadLimit(1 << 30) err := wsjson.Read(ctx, c, &act) assert.Success(tb, err) diff --git a/example_test.go b/example_test.go index 4cc0cf11..4eadf2f5 100644 --- a/example_test.go +++ b/example_test.go @@ -25,7 +25,7 @@ func ExampleAccept() { ctx, cancel := context.WithTimeout(r.Context(), time.Second*10) defer cancel() - var v interface{} + var v any err = wsjson.Read(ctx, c, &v) if err != nil { log.Println(err) diff --git a/internal/errd/wrap.go b/internal/errd/wrap.go index 6e779131..c80d0a65 100644 --- a/internal/errd/wrap.go +++ b/internal/errd/wrap.go @@ -7,7 +7,7 @@ import ( // Wrap wraps err with fmt.Errorf if err is non nil. // Intended for use with defer and a named error return. // Inspired by https://github.com/golang/go/issues/32676. -func Wrap(err *error, f string, v ...interface{}) { +func Wrap(err *error, f string, v ...any) { if *err != nil { *err = fmt.Errorf(f+": %w", append(v, *err)...) } diff --git a/internal/examples/chat/chat.go b/internal/examples/chat/chat.go index 29f304b7..cc24ac7c 100644 --- a/internal/examples/chat/chat.go +++ b/internal/examples/chat/chat.go @@ -31,7 +31,7 @@ type chatServer struct { // logf controls where logs are sent. // Defaults to log.Printf. - logf func(f string, v ...interface{}) + logf func(f string, v ...any) // serveMux routes the various endpoints to the appropriate handler. serveMux http.ServeMux diff --git a/internal/examples/echo/server.go b/internal/examples/echo/server.go index 37e2f2c4..5748b110 100644 --- a/internal/examples/echo/server.go +++ b/internal/examples/echo/server.go @@ -17,7 +17,7 @@ import ( // only allows one message every 100ms with a 10 message burst. type echoServer struct { // logf controls where logs are sent. - logf func(f string, v ...interface{}) + logf func(f string, v ...any) } func (s echoServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/internal/test/assert/assert.go b/internal/test/assert/assert.go index 1b90cc9f..7fd98b08 100644 --- a/internal/test/assert/assert.go +++ b/internal/test/assert/assert.go @@ -9,7 +9,7 @@ import ( ) // Equal asserts exp == act. -func Equal(t testing.TB, name string, exp, got interface{}) { +func Equal(t testing.TB, name string, exp, got any) { t.Helper() if !reflect.DeepEqual(exp, got) { @@ -36,7 +36,7 @@ func Error(t testing.TB, err error) { } // Contains asserts the fmt.Sprint(v) contains sub. -func Contains(t testing.TB, v interface{}, sub string) { +func Contains(t testing.TB, v any, sub string) { t.Helper() s := fmt.Sprint(v) diff --git a/internal/thirdparty/gin_test.go b/internal/thirdparty/gin_test.go index bd30ebdd..4c88337c 100644 --- a/internal/thirdparty/gin_test.go +++ b/internal/thirdparty/gin_test.go @@ -42,7 +42,7 @@ func TestGin(t *testing.T) { err = wsjson.Write(ctx, c, "hello") assert.Success(t, err) - var v interface{} + var v any err = wsjson.Read(ctx, c, &v) assert.Success(t, err) assert.Equal(t, "read msg", "hello", v) diff --git a/internal/wsjs/wsjs_js.go b/internal/wsjs/wsjs_js.go index 11eb59cb..45ecf49d 100644 --- a/internal/wsjs/wsjs_js.go +++ b/internal/wsjs/wsjs_js.go @@ -33,7 +33,7 @@ func New(url string, protocols []string) (c WebSocket, err error) { c = WebSocket{} }) - jsProtocols := make([]interface{}, len(protocols)) + jsProtocols := make([]any, len(protocols)) for i, p := range protocols { jsProtocols[i] = p } @@ -57,7 +57,7 @@ func (c WebSocket) setBinaryType(typ string) { } func (c WebSocket) addEventListener(eventType string, fn func(e js.Value)) func() { - f := js.FuncOf(func(this js.Value, args []js.Value) interface{} { + f := js.FuncOf(func(this js.Value, args []js.Value) any { fn(args[0]) return nil }) @@ -97,7 +97,7 @@ func (c WebSocket) OnError(fn func(e js.Value)) (remove func()) { // MessageEvent is the type passed to a message handler. type MessageEvent struct { // string or []byte. - Data interface{} + Data any // There are more fields to the interface but we don't use them. // See https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent @@ -106,7 +106,7 @@ type MessageEvent struct { // OnMessage registers a function to be called when the WebSocket receives a message. func (c WebSocket) OnMessage(fn func(m MessageEvent)) (remove func()) { return c.addEventListener("message", func(e js.Value) { - var data interface{} + var data any arrayBuffer := e.Get("data") if arrayBuffer.Type() == js.TypeString { diff --git a/wsjson/wsjson.go b/wsjson/wsjson.go index 05e7cfa1..ffa068bf 100644 --- a/wsjson/wsjson.go +++ b/wsjson/wsjson.go @@ -14,11 +14,11 @@ import ( // Read reads a JSON message from c into v. // It will reuse buffers in between calls to avoid allocations. -func Read(ctx context.Context, c *websocket.Conn, v interface{}) error { +func Read(ctx context.Context, c *websocket.Conn, v any) error { return read(ctx, c, v) } -func read(ctx context.Context, c *websocket.Conn, v interface{}) (err error) { +func read(ctx context.Context, c *websocket.Conn, v any) (err error) { defer errd.Wrap(&err, "failed to read JSON message") _, r, err := c.Reader(ctx) @@ -45,11 +45,11 @@ func read(ctx context.Context, c *websocket.Conn, v interface{}) (err error) { // Write writes the JSON message v to c. // It will reuse buffers in between calls to avoid allocations. -func Write(ctx context.Context, c *websocket.Conn, v interface{}) error { +func Write(ctx context.Context, c *websocket.Conn, v any) error { return write(ctx, c, v) } -func write(ctx context.Context, c *websocket.Conn, v interface{}) (err error) { +func write(ctx context.Context, c *websocket.Conn, v any) (err error) { defer errd.Wrap(&err, "failed to write JSON message") // json.Marshal cannot reuse buffers between calls as it has to return From d869c252b8160e03e45714673064797649fd6a15 Mon Sep 17 00:00:00 2001 From: Jacalz Date: Mon, 7 Jul 2025 20:10:56 +0200 Subject: [PATCH 2/5] Minor tidies thanks to gofumpt --- compress.go | 6 ++++-- dial_test.go | 1 - export_test.go | 10 ++++++---- netconn.go | 3 +-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compress.go b/compress.go index 1f3adcfb..7a667ce2 100644 --- a/compress.go +++ b/compress.go @@ -168,8 +168,10 @@ type slidingWindow struct { buf []byte } -var swPoolMu sync.RWMutex -var swPool = map[int]*sync.Pool{} +var ( + swPoolMu sync.RWMutex + swPool = map[int]*sync.Pool{} +) func slidingWindowPool(n int) *sync.Pool { swPoolMu.RLock() diff --git a/dial_test.go b/dial_test.go index f94cd73b..345886bf 100644 --- a/dial_test.go +++ b/dial_test.go @@ -172,7 +172,6 @@ func Test_verifyHostOverride(t *testing.T) { c.CloseNow() }) } - } type mockBody struct { diff --git a/export_test.go b/export_test.go index d3443991..aaad894c 100644 --- a/export_test.go +++ b/export_test.go @@ -30,9 +30,11 @@ func (c *Conn) RecordBytesRead() *int { var ErrClosed = net.ErrClosed -var ExportedDial = dial -var SecWebSocketAccept = secWebSocketAccept -var SecWebSocketKey = secWebSocketKey -var VerifyServerResponse = verifyServerResponse +var ( + ExportedDial = dial + SecWebSocketAccept = secWebSocketAccept + SecWebSocketKey = secWebSocketKey + VerifyServerResponse = verifyServerResponse +) var CompressionModeOpts = CompressionMode.opts diff --git a/netconn.go b/netconn.go index b118e4d3..1f73b04b 100644 --- a/netconn.go +++ b/netconn.go @@ -188,8 +188,7 @@ func (nc *netConn) read(p []byte) (int, error) { return n, err } -type websocketAddr struct { -} +type websocketAddr struct{} func (a websocketAddr) Network() string { return "websocket" From 0b61cfb37fc44bd8d91df846f6b9f25f6f372c55 Mon Sep 17 00:00:00 2001 From: Jacalz Date: Mon, 7 Jul 2025 20:11:29 +0200 Subject: [PATCH 3/5] Run "go fix ./..." on the codebase --- accept.go | 1 - accept_test.go | 1 - autobahn_test.go | 1 - close.go | 1 - close_test.go | 1 - compress.go | 1 - compress_test.go | 1 - conn.go | 1 - dial.go | 1 - dial_test.go | 1 - doc.go | 1 - export_test.go | 1 - frame_test.go | 1 - internal/test/wstest/pipe.go | 1 - netconn_notjs.go | 1 - read.go | 1 - write.go | 1 - 17 files changed, 17 deletions(-) diff --git a/accept.go b/accept.go index f45fdd0b..0f3b0d16 100644 --- a/accept.go +++ b/accept.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/accept_test.go b/accept_test.go index 3b45ac5c..aeea1d8a 100644 --- a/accept_test.go +++ b/accept_test.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/autobahn_test.go b/autobahn_test.go index e43851c8..20b89609 100644 --- a/autobahn_test.go +++ b/autobahn_test.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket_test diff --git a/close.go b/close.go index f94951dc..2de1a5c2 100644 --- a/close.go +++ b/close.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/close_test.go b/close_test.go index aec582c1..1e04807e 100644 --- a/close_test.go +++ b/close_test.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/compress.go b/compress.go index 7a667ce2..41bd5bdb 100644 --- a/compress.go +++ b/compress.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/compress_test.go b/compress_test.go index d97492cf..5de42706 100644 --- a/compress_test.go +++ b/compress_test.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/conn.go b/conn.go index 42fe89fe..5907bc81 100644 --- a/conn.go +++ b/conn.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/dial.go b/dial.go index 0b11ecbb..f5e4544b 100644 --- a/dial.go +++ b/dial.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/dial_test.go b/dial_test.go index 345886bf..a4bdfdae 100644 --- a/dial_test.go +++ b/dial_test.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket_test diff --git a/doc.go b/doc.go index 03edf129..0c7f8316 100644 --- a/doc.go +++ b/doc.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js // Package websocket implements the RFC 6455 WebSocket protocol. // diff --git a/export_test.go b/export_test.go index aaad894c..e0071922 100644 --- a/export_test.go +++ b/export_test.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/frame_test.go b/frame_test.go index 08874cb5..d0f0f8c1 100644 --- a/frame_test.go +++ b/frame_test.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/internal/test/wstest/pipe.go b/internal/test/wstest/pipe.go index b8cf094d..0e7fdb84 100644 --- a/internal/test/wstest/pipe.go +++ b/internal/test/wstest/pipe.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package wstest diff --git a/netconn_notjs.go b/netconn_notjs.go index f3eb0d66..cab76349 100644 --- a/netconn_notjs.go +++ b/netconn_notjs.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/read.go b/read.go index 2db22435..aab9e141 100644 --- a/read.go +++ b/read.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/write.go b/write.go index 7324de74..fc0ab9b9 100644 --- a/write.go +++ b/write.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket From d88a86d4252069126d5cb5374aa89a04df4ca5f1 Mon Sep 17 00:00:00 2001 From: Jacalz Date: Mon, 7 Jul 2025 20:23:05 +0200 Subject: [PATCH 4/5] Apply a few modernisations suggested by gopls check --- compress_test.go | 2 +- conn_test.go | 14 +++++++------- dial_test.go | 6 +++--- example_test.go | 2 +- frame_test.go | 2 +- mask_test.go | 2 +- write.go | 5 +---- ws_js_test.go | 2 +- 8 files changed, 16 insertions(+), 19 deletions(-) diff --git a/compress_test.go b/compress_test.go index 5de42706..1964c84f 100644 --- a/compress_test.go +++ b/compress_test.go @@ -18,7 +18,7 @@ func Test_slidingWindow(t *testing.T) { const testCount = 99 const maxWindow = 99999 - for i := 0; i < testCount; i++ { + for range testCount { t.Run("", func(t *testing.T) { t.Parallel() diff --git a/conn_test.go b/conn_test.go index af3d973b..58ac394c 100644 --- a/conn_test.go +++ b/conn_test.go @@ -36,7 +36,7 @@ func TestConn(t *testing.T) { return websocket.CompressionMode(xrand.Int(int(websocket.CompressionContextTakeover) + 1)) } - for i := 0; i < 5; i++ { + for range 5 { t.Run("", func(t *testing.T) { tt, c1, c2 := newConnTest(t, &websocket.DialOptions{ CompressionMode: compressionMode(), @@ -50,7 +50,7 @@ func TestConn(t *testing.T) { c1.SetReadLimit(131072) - for i := 0; i < 5; i++ { + for range 5 { err := wstest.Echo(tt.ctx, c1, 131072) assert.Success(t, err) } @@ -76,7 +76,7 @@ func TestConn(t *testing.T) { c1.CloseRead(tt.ctx) c2.CloseRead(tt.ctx) - for i := 0; i < 10; i++ { + for range 10 { err := c1.Ping(tt.ctx) assert.Success(t, err) } @@ -185,7 +185,7 @@ func TestConn(t *testing.T) { const count = 100 errs := make(chan error, count) - for i := 0; i < count; i++ { + for range count { go func() { select { case errs <- c1.Write(tt.ctx, websocket.MessageBinary, msg): @@ -195,7 +195,7 @@ func TestConn(t *testing.T) { }() } - for i := 0; i < count; i++ { + for range count { select { case err := <-errs: assert.Success(t, err) @@ -408,7 +408,7 @@ func TestConn(t *testing.T) { c1.SetReadLimit(131072) - for i := 0; i < 5; i++ { + for range 5 { err := wstest.Echo(tt.ctx, c1, 131072) assert.Success(t, err) } @@ -682,7 +682,7 @@ func assertClose(tb testing.TB, c *websocket.Conn) { func TestConcurrentClosePing(t *testing.T) { t.Parallel() - for i := 0; i < 64; i++ { + for range 64 { func() { c1, c2 := wstest.Pipe(nil, nil) defer c1.CloseNow() diff --git a/dial_test.go b/dial_test.go index a4bdfdae..492ac6b3 100644 --- a/dial_test.go +++ b/dial_test.go @@ -7,6 +7,7 @@ import ( "context" "crypto/rand" "io" + "maps" "net/http" "net/http/httptest" "net/url" @@ -355,11 +356,10 @@ func (fc *forwardProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { } defer resp.Body.Close() - for k, v := range resp.Header { - w.Header()[k] = v - } + maps.Copy(w.Header(), resp.Header) w.Header().Set("PROXIED", "true") w.WriteHeader(resp.StatusCode) + if resprw, ok := resp.Body.(io.ReadWriter); ok { c, brw, err := w.(http.Hijacker).Hijack() if err != nil { diff --git a/example_test.go b/example_test.go index 4eadf2f5..7026e311 100644 --- a/example_test.go +++ b/example_test.go @@ -150,7 +150,7 @@ func ExampleConn_Ping() { // Required to read the Pongs from the server. ctx = c.CloseRead(ctx) - for i := 0; i < 5; i++ { + for range 5 { err = c.Ping(ctx) if err != nil { log.Fatal(err) diff --git a/frame_test.go b/frame_test.go index d0f0f8c1..6b2e21f5 100644 --- a/frame_test.go +++ b/frame_test.go @@ -53,7 +53,7 @@ func TestHeader(t *testing.T) { return r.Intn(2) == 0 } - for i := 0; i < 10000; i++ { + for range 10000 { h := header{ fin: randBool(), rsv1: randBool(), diff --git a/mask_test.go b/mask_test.go index 00a9f0a2..7d6aedd7 100644 --- a/mask_test.go +++ b/mask_test.go @@ -40,7 +40,7 @@ func TestMask(t *testing.T) { func testMask(t *testing.T, name string, fn func(b []byte, key uint32) uint32) { t.Run(name, func(t *testing.T) { t.Parallel() - for i := 0; i < 9999; i++ { + for range 9999 { keyb := make([]byte, 4) _, err := rand.Read(keyb) assert.Success(t, err) diff --git a/write.go b/write.go index fc0ab9b9..7104b227 100644 --- a/write.go +++ b/write.go @@ -350,10 +350,7 @@ func (c *Conn) writeFramePayload(p []byte) (n int, err error) { // Start of next write in the buffer. i := c.bw.Buffered() - j := len(p) - if j > c.bw.Available() { - j = c.bw.Available() - } + j := min(len(p), c.bw.Available()) _, err := c.bw.Write(p[:j]) if err != nil { diff --git a/ws_js_test.go b/ws_js_test.go index b56ad16b..1fa242f4 100644 --- a/ws_js_test.go +++ b/ws_js_test.go @@ -28,7 +28,7 @@ func TestWasm(t *testing.T) { assert.Equal(t, "response code", http.StatusSwitchingProtocols, resp.StatusCode) c.SetReadLimit(65536) - for i := 0; i < 10; i++ { + for range 10 { err = wstest.Echo(ctx, c, 65536) assert.Success(t, err) } From 8088934934e38a19ade5e09886f571f06232d7af Mon Sep 17 00:00:00 2001 From: Jacalz Date: Mon, 7 Jul 2025 20:23:55 +0200 Subject: [PATCH 5/5] Remove unused parameter suggested by gopls check --- ws_js.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ws_js.go b/ws_js.go index 5e324c47..8d52aeab 100644 --- a/ws_js.go +++ b/ws_js.go @@ -196,7 +196,7 @@ func (c *Conn) Ping(ctx context.Context) error { // Write writes a message of the given type to the connection. // Always non blocking. func (c *Conn) Write(ctx context.Context, typ MessageType, p []byte) error { - err := c.write(ctx, typ, p) + err := c.write(typ, p) if err != nil { // Have to ensure the WebSocket is closed after a write error // to match the Go API. It can only error if the message type @@ -210,7 +210,7 @@ func (c *Conn) Write(ctx context.Context, typ MessageType, p []byte) error { return nil } -func (c *Conn) write(ctx context.Context, typ MessageType, p []byte) error { +func (c *Conn) write(typ MessageType, p []byte) error { if c.isClosed() { return net.ErrClosed }