Description
Version 1.11.0 does not work anymore with github.com/coder/websocket, because it rejects writting headers before Hijack().
In github.com/coder/websocket a fix has been made in 2019 to work with Gin, which calls WriteHeaderNow()
before Hijack() in its Accept()
function.
But responseWriter.Hijack()
first tests for w.Written()
, which returns true as size is 0, and returns an error (errHijackAlreadyWritten
).
So, for maximum compatibility, and unless there is a good reason to block this, I think you should change
if w.Written() {
to if w.size>0 {
.
Gin Version
1.11.0
Can you reproduce the bug?
Yes
Source Code
package main
import (
"context"
"log"
"time"
"github.com/coder/websocket"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.Any("/ws", func(c *gin.Context) {
ws, err := websocket.Accept(c.Writer, c.Request, nil)
if err != nil {
// This is were we receive errHijackAlreadyWritten
log.Print("Websocket upgrade failed: ", err)
return
}
defer ws.Close(websocket.StatusNormalClosure, "")
})
go r.Run()
// Let the server start...
time.Sleep(time.Second)
// Try to open the websocket
ws, _, err := websocket.Dial(context.Background(), "ws://localhost:8080/ws", nil)
if err != nil {
log.Fatalf("FAILED to dial websocket: %v", err)
}
defer ws.Close(websocket.StatusGoingAway, "leaving")
}
Go Version
1.25.1
Operating System
UbuntU 24.04
Comment From: appleboy
See the PR: https://github.com/gin-gonic/gin/pull/4373