Fix panic in WebSocket handling by manually writing headers instead of using r.Write
This commit is contained in:
@@ -180,10 +180,21 @@ func startHttpProxy(port string) {
|
|||||||
}
|
}
|
||||||
defer clientConn.Close()
|
defer clientConn.Close()
|
||||||
|
|
||||||
// Reconstruct request line and headers to send to backend
|
// Manual Request writing to avoid touching Body after Hijack/Panic
|
||||||
// We can use r.Write but it writes to the channel
|
// Request Line
|
||||||
if err := r.Write(ch); err != nil {
|
reqLine := fmt.Sprintf("%s %s %s\r\n", r.Method, r.RequestURI, r.Proto)
|
||||||
log.Printf("Error writing websocket request to backend: %v", err)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +203,12 @@ func startHttpProxy(port string) {
|
|||||||
|
|
||||||
// Copy existing buffer from hijack + future reads -> backend
|
// Copy existing buffer from hijack + future reads -> backend
|
||||||
go func() {
|
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 {
|
if bufrw.Reader.Buffered() > 0 {
|
||||||
io.CopyN(ch, bufrw, int64(bufrw.Reader.Buffered()))
|
io.CopyN(ch, bufrw, int64(bufrw.Reader.Buffered()))
|
||||||
}
|
}
|
||||||
@@ -201,7 +217,12 @@ func startHttpProxy(port string) {
|
|||||||
|
|
||||||
// Backend -> Browser
|
// Backend -> Browser
|
||||||
go func() {
|
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)
|
io.Copy(clientConn, ch)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user