mirror of
https://github.com/fatedier/frp.git
synced 2026-07-16 09:19:17 +08:00
fix(websocket): send tunnel payload as binary frames (#5363)
The ws/wss transport carries a raw byte stream (yamux), but the golang.org/x/net/websocket Conn defaults to text frames (PayloadType TextFrame). Per RFC 6455 §5.6 a text frame must contain valid UTF-8, so RFC-compliant intermediaries (API gateways / reverse proxies) validate the payload and close the connection when the binary tunnel data is not valid UTF-8. This goes unnoticed peer-to-peer because x/net/websocket does not validate UTF-8 on read, but it breaks the connection through a compliant validating proxy. Set PayloadType to BinaryFrame on both the server listener and the client dialer so the tunnel is framed as binary.
This commit is contained in:
@@ -45,6 +45,11 @@ func DialHookWebsocket(protocol string, host string) libnet.AfterHookFunc {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
// The tunnel payload is a raw byte stream (yamux), not UTF-8 text.
|
||||||
|
// Send it as binary frames; otherwise RFC 6455-compliant intermediaries
|
||||||
|
// (e.g. API gateways/reverse proxies) UTF-8-validate the default text
|
||||||
|
// frames and close the connection on invalid bytes.
|
||||||
|
conn.PayloadType = websocket.BinaryFrame
|
||||||
return ctx, conn, nil
|
return ctx, conn, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) {
|
|||||||
|
|
||||||
muxer := http.NewServeMux()
|
muxer := http.NewServeMux()
|
||||||
muxer.Handle(FrpWebsocketPath, websocket.Handler(func(c *websocket.Conn) {
|
muxer.Handle(FrpWebsocketPath, websocket.Handler(func(c *websocket.Conn) {
|
||||||
|
// The tunnel payload is a raw byte stream (yamux), not UTF-8 text.
|
||||||
|
// Send it as binary frames; otherwise RFC 6455-compliant intermediaries
|
||||||
|
// (e.g. API gateways/reverse proxies) UTF-8-validate the default text
|
||||||
|
// frames and close the connection on invalid bytes.
|
||||||
|
c.PayloadType = websocket.BinaryFrame
|
||||||
notifyCh := make(chan struct{})
|
notifyCh := make(chan struct{})
|
||||||
conn := WrapCloseNotifyConn(c, func(_ error) {
|
conn := WrapCloseNotifyConn(c, func(_ error) {
|
||||||
close(notifyCh)
|
close(notifyCh)
|
||||||
|
|||||||
Reference in New Issue
Block a user