@@ -20,6 +20,11 @@ pub enum HttpServerRequest {
2020 WebSocketOpen {
2121 path : String ,
2222 channel_id : u32 ,
23+ #[ serde( default ) ]
24+ source_socket_addr : Option < String > ,
25+ /// IP address from proxy headers (X-Forwarded-For, X-Real-IP, Cf-Connecting-Ip)
26+ #[ serde( default ) ]
27+ forwarded_for : Option < String > ,
2328 } ,
2429 /// Processes can both SEND and RECEIVE this kind of [`crate::Request`]
2530 /// (send as [`HttpServerAction::WebSocketPush`]).
@@ -300,6 +305,8 @@ pub struct HttpServer {
300305 ws_paths : HashMap < String , WsBindingConfig > ,
301306 /// A mapping of WebSocket paths to the channels that are open on them.
302307 ws_channels : HashMap < String , HashSet < u32 > > ,
308+ /// A mapping of WebSocket channel IDs to their client socket addresses.
309+ ws_channel_addrs : HashMap < u32 , String > ,
303310 /// The timeout given for `http-server:distro:sys` to respond to a configuration request.
304311 pub timeout : u64 ,
305312}
@@ -451,6 +458,7 @@ impl HttpServer {
451458 http_paths : HashMap :: new ( ) ,
452459 ws_paths : HashMap :: new ( ) ,
453460 ws_channels : HashMap :: new ( ) ,
461+ ws_channel_addrs : HashMap :: new ( ) ,
454462 timeout,
455463 }
456464 }
@@ -983,18 +991,35 @@ impl HttpServer {
983991 }
984992
985993 /// Handle a WebSocket open event from the HTTP server.
986- pub fn handle_websocket_open ( & mut self , path : & str , channel_id : u32 ) {
994+ pub fn handle_websocket_open (
995+ & mut self ,
996+ path : & str ,
997+ channel_id : u32 ,
998+ source_socket_addr : Option < String > ,
999+ forwarded_for : Option < String > ,
1000+ ) {
9871001 self . ws_channels
9881002 . entry ( path. to_string ( ) )
9891003 . or_insert ( HashSet :: new ( ) )
9901004 . insert ( channel_id) ;
1005+ // Store the client IP, preferring forwarded_for (from proxy headers) over socket addr
1006+ let client_ip = forwarded_for. or ( source_socket_addr) ;
1007+ if let Some ( ip) = client_ip {
1008+ self . ws_channel_addrs . insert ( channel_id, ip) ;
1009+ }
1010+ }
1011+
1012+ /// Get the socket address for a WebSocket channel.
1013+ pub fn get_ws_channel_addr ( & self , channel_id : u32 ) -> Option < & String > {
1014+ self . ws_channel_addrs . get ( & channel_id)
9911015 }
9921016
9931017 /// Handle a WebSocket close event from the HTTP server.
9941018 pub fn handle_websocket_close ( & mut self , channel_id : u32 ) {
9951019 self . ws_channels . iter_mut ( ) . for_each ( |( _, channels) | {
9961020 channels. remove ( & channel_id) ;
9971021 } ) ;
1022+ self . ws_channel_addrs . remove ( & channel_id) ;
9981023 }
9991024
10001025 pub fn parse_request ( & self , body : & [ u8 ] ) -> Result < HttpServerRequest , HttpServerError > {
@@ -1024,8 +1049,13 @@ impl HttpServer {
10241049 channel_id,
10251050 message_type,
10261051 } => ws_handler ( channel_id, message_type, last_blob ( ) . unwrap_or_default ( ) ) ,
1027- HttpServerRequest :: WebSocketOpen { path, channel_id } => {
1028- self . handle_websocket_open ( & path, channel_id) ;
1052+ HttpServerRequest :: WebSocketOpen {
1053+ path,
1054+ channel_id,
1055+ source_socket_addr,
1056+ forwarded_for,
1057+ } => {
1058+ self . handle_websocket_open ( & path, channel_id, source_socket_addr, forwarded_for) ;
10291059 }
10301060 HttpServerRequest :: WebSocketClose ( channel_id) => {
10311061 self . handle_websocket_close ( channel_id) ;
0 commit comments