Fix panic in WebSocket handling by manually writing headers instead of using r.Write

This commit is contained in:
Jose Luis Montañes Ojados
2026-01-27 13:32:45 +01:00
parent bec63c3283
commit 34af75aaa1

View File

@@ -180,10 +180,21 @@ func startHttpProxy(port string) {
}
defer clientConn.Close()
// Reconstruct request line and headers to send to backend
// We can use r.Write but it writes to the channel
if err := r.Write(ch); err != nil {
log.Printf("Error writing websocket request to backend: %v", err)
// Manual Request writing to avoid touching Body after Hijack/Panic
// Request Line
reqLine := fmt.Sprintf("%s %s %s\r\n", r.Method, r.RequestURI, r.Proto)
if _, err := io.WriteString(ch, reqLine); err != nil {
log.Printf("Error writing websocket request line: %v", err)
return
}
// Headers
if err := r.Header.Write(ch); err != nil {
log.Printf("Error writing websocket headers: %v", err)
return
}
// End of headers
if _, err := io.WriteString(ch, "\r\n"); err != nil {
log.Printf("Error writing websocket header terminator: %v", err)
return
}
@@ -192,7 +203,12 @@ func startHttpProxy(port string) {
// Copy existing buffer from hijack + future reads -> backend
go func() {
defer wg.Done()
defer func() {
if r := recover(); r != nil {
log.Printf("Recovered from panic in WS writer: %v", r)
}
wg.Done()
}()
if bufrw.Reader.Buffered() > 0 {
io.CopyN(ch, bufrw, int64(bufrw.Reader.Buffered()))
}
@@ -201,7 +217,12 @@ func startHttpProxy(port string) {
// Backend -> Browser
go func() {
defer wg.Done()
defer func() {
if r := recover(); r != nil {
log.Printf("Recovered from panic in WS reader: %v", r)
}
wg.Done()
}()
io.Copy(clientConn, ch)
}()