diff --git a/crates/server/src/http.rs b/crates/server/src/http.rs index 7659ad6..4d63fb0 100644 --- a/crates/server/src/http.rs +++ b/crates/server/src/http.rs @@ -63,7 +63,7 @@ pub struct ServerInfo { pub struct HttpServer { pub offer_tx: Sender<(i32, i32, String)>, - pub accept_rx: async_broadcast::InactiveReceiver<(i32, Option)>, + pub accept_rx: async_broadcast::InactiveReceiver<(i32, Result)>, pub appstate: Arc>, pub request_count: AtomicI32, pub db: DatabaseConnection, @@ -456,18 +456,15 @@ async fn stream_handler( }) .await { - Ok(Some(Some(reply))) => { + Ok(Some(Ok(reply))) => { return Ok(Response::builder() .status(StatusCode::CREATED) .header("content-type", "application/sdp") .body(reply) .unwrap()); } - Ok(Some(None)) => { - return Ok(Response::builder() - .status(StatusCode::UNSUPPORTED_MEDIA_TYPE) - .body(String::new()) - .unwrap()); + Ok(Some(Err(codec))) => { + return Err(HttpError::WhepCodecError(codec)); } Ok(None) => { info!( diff --git a/crates/server/src/http_error.rs b/crates/server/src/http_error.rs index 3f22566..188cf03 100644 --- a/crates/server/src/http_error.rs +++ b/crates/server/src/http_error.rs @@ -25,6 +25,8 @@ pub enum HttpError { Unprocessable(String), #[error("not acceptable: {0}")] NotAcceptable(String), + #[error("unsupported codec: {0}")] + WhepCodecError(String), #[error("internal error")] Internal, } @@ -40,6 +42,7 @@ impl HttpError { Self::BadRequest(_) => StatusCode::BAD_REQUEST, Self::Unprocessable(_) => StatusCode::UNPROCESSABLE_ENTITY, Self::NotAcceptable(_) => StatusCode::NOT_ACCEPTABLE, + Self::WhepCodecError(_) => StatusCode::UNSUPPORTED_MEDIA_TYPE, } } } @@ -47,12 +50,14 @@ impl HttpError { impl IntoResponse for HttpError { fn into_response(self) -> Response { let status = self.status(); - // Only surface a message body for client (4xx) errors; keep an empty - // body for 5xx so internal details aren't leaked. - let body = if status.is_client_error() { - self.to_string() - } else { - String::new() + let body = match self { + // The WHEP client (frontend) reads this body as the rejected + // codec, so send it bare rather than the full error string. + Self::WhepCodecError(codec) => codec, + // Only surface a message body for client (4xx) errors; keep an + // empty body for 5xx so internal details aren't leaked. + e if status.is_client_error() => e.to_string(), + _ => String::new(), }; (status, body).into_response() } diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs index a03d0f5..10e4621 100644 --- a/crates/server/src/main.rs +++ b/crates/server/src/main.rs @@ -102,7 +102,7 @@ async fn main() -> Result<(), Box> { // String_Label, // Offer_body - let (answer_tx, answer_rx) = broadcast::<(i32, Option)>(64); + let (answer_tx, answer_rx) = broadcast::<(i32, Result)>(64); // Request_Id, // Answer_body diff --git a/crates/server/src/webrtc.rs b/crates/server/src/webrtc.rs index e4f5eb9..ecef992 100644 --- a/crates/server/src/webrtc.rs +++ b/crates/server/src/webrtc.rs @@ -18,11 +18,11 @@ use crate::{ }; pub struct Webrtc { -pub offer_rx: Receiver<(i32, i32, String)>, -pub accept_tx: async_broadcast::Sender<(i32, Option)>, -pub sessions_ref: Arc>, -pub proxy: Arc, -pub db: DatabaseConnection, + pub offer_rx: Receiver<(i32, i32, String)>, + pub accept_tx: async_broadcast::Sender<(i32, Result)>, + pub sessions_ref: Arc>, + pub proxy: Arc, + pub db: DatabaseConnection, } impl Webrtc { @@ -40,7 +40,7 @@ impl Webrtc { request_id, stream_id, "stream key not found in DB, rejecting offer" ); - self.accept_tx.broadcast((request_id, None)).await.unwrap(); + self.accept_tx.broadcast((request_id, Err(String::new()))).await.unwrap(); continue; } if let Err(ref e) = stream_key { @@ -48,7 +48,7 @@ impl Webrtc { request_id, stream_id, "DB error looking up stream key: {:?}", e ); - self.accept_tx.broadcast((request_id, None)).await.unwrap(); + self.accept_tx.broadcast((request_id, Err(String::new()))).await.unwrap(); continue; } @@ -134,7 +134,7 @@ impl Webrtc { Ok(sdp) => sdp, Err(e) => { warn!(request_id, stream_id, "malformed SDP offer: {:?}", e); - self.accept_tx.broadcast((request_id, None)).await.unwrap(); + self.accept_tx.broadcast((request_id, Err(String::new()))).await.unwrap(); continue; } }; @@ -179,11 +179,14 @@ impl Webrtc { "no video codec negotiated — browser likely doesn't support {:?}; rejecting offer", stream_codec ); - self.accept_tx.broadcast((request_id, None)).await.unwrap(); - continue; - } + self.accept_tx + .broadcast((request_id, Err(format!("{:?}", stream_codec)))) + .await + .unwrap(); + continue; + } - let ufrag = answer_sdp + let ufrag = answer_sdp .lines() .find(|l| l.starts_with("a=ice-ufrag:")) .and_then(|l| l.strip_prefix("a=ice-ufrag:")) @@ -193,7 +196,7 @@ impl Webrtc { debug!(request_id, "sending answer back"); self.accept_tx - .broadcast((request_id, Some(answer_sdp))) + .broadcast((request_id, Ok(answer_sdp))) .await .unwrap(); @@ -310,8 +313,8 @@ impl Webrtc { } _ => {} }, - Err(e) => { - error!("poll_output error (connection closing): {:?}", e); + Err(_e) => { + // error!("poll_output error (connection closing): {:?}", e); return; } } @@ -487,6 +490,5 @@ impl Webrtc { { warn!("RTP write error: {:?}", e); } + } } -} -