//! # RTC Relay controller //! //! @author Pierre Hubert use actix::{ActorContext, StreamHandler}; use actix_web_actors::ws::{Message, ProtocolError}; use crate::data::config::conf; struct RtcRelayActor {} impl actix::Actor for RtcRelayActor { type Context = actix_web_actors::ws::WebsocketContext; } impl StreamHandler> for RtcRelayActor { fn handle(&mut self, msg: Result, ctx: &mut Self::Context) { let msg = match msg { Err(_) => { ctx.stop(); return; } Ok(msg) => msg }; if conf().verbose_mode { println!("RTC RELAY WS MESSAGE: {:?}", msg); } } } /// Establish a new connection with the RTC relay /// /// Debug with /// ```js /// ws = new WebSocket("ws://0.0.0.0:3000/rtc_proxy/ws"); /// ws.onmessage = (msg) => console.log("WS msg", msg); /// ws.onopen = () => console.log("Socket is open !"); /// ws.onerror = (e) => console.log("WS ERROR !", e); /// ws.onclose = (e) => console.log("WS CLOSED!"); /// ``` pub async fn open_ws(req: actix_web::HttpRequest, stream: actix_web::web::Payload) -> Result { let ip = req.peer_addr().unwrap(); // Check if video calls are enabled if conf().rtc_relay.is_none() { eprintln!("A relay from {} tried to connect to the server but the relay is disabled!", ip); return Ok(actix_web::HttpResponse::BadRequest().body("RTC Relay not configured!")); } let conf = conf().rtc_relay.as_ref().unwrap(); // Check remote IP address if !ip.ip().to_string().eq(&conf.ip) { eprintln!("A relay from {} tried to connect to the server but the IP address is not authorized!", ip); return Ok(actix_web::HttpResponse::Unauthorized().body("Access denied!")); } // Check the token if !req.query_string().eq(&format!("token={}", &conf.token)) { eprintln!("A relay from {} tried to connect with an invalid access token!", ip); return Ok(actix_web::HttpResponse::Unauthorized().body("Invalid token!")); } // Start the actor actix_web_actors::ws::start(RtcRelayActor {}, &req, stream) }