You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
middleware/websocket: Conn.Param always returns "" (route params are never captured), and on epoll and io_uring Conn.IP and Conn.RemoteAddr return "" and nil #721
Conn.Param always returns "", on every engine, because the route params are never captured.
On epoll and io_uring, Conn.IP() returns "" and Conn.RemoteAddr() returns nil.
#714 guessed that Conn.Param "is very likely affected" by the query aliasing. The audit it called for found that the real defect is different: Param is never captured at all. Neither defect is a view retention.
Mechanism
Param.Conn.Param reads c.params (middleware/websocket/conn.go:950 at 9f4d89b). Nothing in the package assigns params: setupConn (websocket.go:308-322) sets only headers and query, and git log -S'ws.params' finds no commit that ever did. This has been the case since the middleware landed in v1.3.4 (feat: v1.3.4 realtime middleware (WebSocket + SSE + Protobuf) #229).
IP and RemoteAddr. Both read c.conn (conn.go:880-925). Only the hijack path sets it (newConn, used by the std engine). The engine path builds its Conn with newEngineConn (conn.go:135-157), which has no net.Conn, and the peer address that c.RemoteAddr() holds on the Context (context_request.go:654) is not captured.
Reproduction
The evidence test is TestC714EvidenceParamAndIP, kept with the #714 evidence. The route is GET /ws/:room, and the handler reports c.Param("room"), c.IP() and c.RemoteAddr() for an upgrade to /ws/lobby.
engine
Param("room")
IP()
RemoteAddr()
std
""
127.0.0.1
127.0.0.1:<port>
epoll
""
""
<nil>
io_uring
""
""
<nil>
Docker linux/arm64 (--cpus 4), kernel 7.0.12-linuxkit, memlock 8 MiB, go test -race.
Fix direction
Capture the route params and the peer address at upgrade, next to captureQuery. Clone every string, for the reason #714 gives: on the native engines a param value is a view of the receive buffer, and the Conn outlives the request. Keep the peer address as a string for IP(), and return a net.Addr built from it for RemoteAddr(), so the engine path answers what the hijack path does.
Summary
In
middleware/websocket:Conn.Paramalways returns"", on every engine, because the route params are never captured.Conn.IP()returns""andConn.RemoteAddr()returnsnil.#714 guessed that
Conn.Param"is very likely affected" by the query aliasing. The audit it called for found that the real defect is different:Paramis never captured at all. Neither defect is a view retention.Mechanism
Conn.Paramreadsc.params(middleware/websocket/conn.go:950at 9f4d89b). Nothing in the package assignsparams:setupConn(websocket.go:308-322) sets only headers and query, andgit log -S'ws.params'finds no commit that ever did. This has been the case since the middleware landed in v1.3.4 (feat: v1.3.4 realtime middleware (WebSocket + SSE + Protobuf) #229).c.conn(conn.go:880-925). Only the hijack path sets it (newConn, used by the std engine). The engine path builds its Conn withnewEngineConn(conn.go:135-157), which has nonet.Conn, and the peer address thatc.RemoteAddr()holds on the Context (context_request.go:654) is not captured.Reproduction
The evidence test is
TestC714EvidenceParamAndIP, kept with the #714 evidence. The route isGET /ws/:room, and the handler reportsc.Param("room"),c.IP()andc.RemoteAddr()for an upgrade to/ws/lobby.""127.0.0.1127.0.0.1:<port>""""<nil>""""<nil>Docker linux/arm64 (
--cpus 4), kernel 7.0.12-linuxkit, memlock 8 MiB,go test -race.Fix direction
Capture the route params and the peer address at upgrade, next to
captureQuery. Clone every string, for the reason #714 gives: on the native engines a param value is a view of the receive buffer, and the Conn outlives the request. Keep the peer address as a string forIP(), and return anet.Addrbuilt from it forRemoteAddr(), so the engine path answers what the hijack path does.