fix(http): reject unsupported codecs with 415 and the codec as body
This commit is contained in:
@@ -63,7 +63,7 @@ pub struct ServerInfo {
|
|||||||
|
|
||||||
pub struct HttpServer {
|
pub struct HttpServer {
|
||||||
pub offer_tx: Sender<(i32, i32, String)>,
|
pub offer_tx: Sender<(i32, i32, String)>,
|
||||||
pub accept_rx: async_broadcast::InactiveReceiver<(i32, Option<String>)>,
|
pub accept_rx: async_broadcast::InactiveReceiver<(i32, Result<String, String>)>,
|
||||||
pub appstate: Arc<Mutex<AppState>>,
|
pub appstate: Arc<Mutex<AppState>>,
|
||||||
pub request_count: AtomicI32,
|
pub request_count: AtomicI32,
|
||||||
pub db: DatabaseConnection,
|
pub db: DatabaseConnection,
|
||||||
@@ -456,18 +456,15 @@ async fn stream_handler(
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(Some(Some(reply))) => {
|
Ok(Some(Ok(reply))) => {
|
||||||
return Ok(Response::builder()
|
return Ok(Response::builder()
|
||||||
.status(StatusCode::CREATED)
|
.status(StatusCode::CREATED)
|
||||||
.header("content-type", "application/sdp")
|
.header("content-type", "application/sdp")
|
||||||
.body(reply)
|
.body(reply)
|
||||||
.unwrap());
|
.unwrap());
|
||||||
}
|
}
|
||||||
Ok(Some(None)) => {
|
Ok(Some(Err(codec))) => {
|
||||||
return Ok(Response::builder()
|
return Err(HttpError::WhepCodecError(codec));
|
||||||
.status(StatusCode::UNSUPPORTED_MEDIA_TYPE)
|
|
||||||
.body(String::new())
|
|
||||||
.unwrap());
|
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
info!(
|
info!(
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ pub enum HttpError {
|
|||||||
Unprocessable(String),
|
Unprocessable(String),
|
||||||
#[error("not acceptable: {0}")]
|
#[error("not acceptable: {0}")]
|
||||||
NotAcceptable(String),
|
NotAcceptable(String),
|
||||||
|
#[error("unsupported codec: {0}")]
|
||||||
|
WhepCodecError(String),
|
||||||
#[error("internal error")]
|
#[error("internal error")]
|
||||||
Internal,
|
Internal,
|
||||||
}
|
}
|
||||||
@@ -40,6 +42,7 @@ impl HttpError {
|
|||||||
Self::BadRequest(_) => StatusCode::BAD_REQUEST,
|
Self::BadRequest(_) => StatusCode::BAD_REQUEST,
|
||||||
Self::Unprocessable(_) => StatusCode::UNPROCESSABLE_ENTITY,
|
Self::Unprocessable(_) => StatusCode::UNPROCESSABLE_ENTITY,
|
||||||
Self::NotAcceptable(_) => StatusCode::NOT_ACCEPTABLE,
|
Self::NotAcceptable(_) => StatusCode::NOT_ACCEPTABLE,
|
||||||
|
Self::WhepCodecError(_) => StatusCode::UNSUPPORTED_MEDIA_TYPE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,12 +50,14 @@ impl HttpError {
|
|||||||
impl IntoResponse for HttpError {
|
impl IntoResponse for HttpError {
|
||||||
fn into_response(self) -> Response<Body> {
|
fn into_response(self) -> Response<Body> {
|
||||||
let status = self.status();
|
let status = self.status();
|
||||||
// Only surface a message body for client (4xx) errors; keep an empty
|
let body = match self {
|
||||||
// body for 5xx so internal details aren't leaked.
|
// The WHEP client (frontend) reads this body as the rejected
|
||||||
let body = if status.is_client_error() {
|
// codec, so send it bare rather than the full error string.
|
||||||
self.to_string()
|
Self::WhepCodecError(codec) => codec,
|
||||||
} else {
|
// Only surface a message body for client (4xx) errors; keep an
|
||||||
String::new()
|
// 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()
|
(status, body).into_response()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
// String_Label,
|
// String_Label,
|
||||||
// Offer_body
|
// Offer_body
|
||||||
|
|
||||||
let (answer_tx, answer_rx) = broadcast::<(i32, Option<String>)>(64);
|
let (answer_tx, answer_rx) = broadcast::<(i32, Result<String, String>)>(64);
|
||||||
// Request_Id,
|
// Request_Id,
|
||||||
// Answer_body
|
// Answer_body
|
||||||
|
|
||||||
|
|||||||
+16
-14
@@ -18,11 +18,11 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub struct Webrtc {
|
pub struct Webrtc {
|
||||||
pub offer_rx: Receiver<(i32, i32, String)>,
|
pub offer_rx: Receiver<(i32, i32, String)>,
|
||||||
pub accept_tx: async_broadcast::Sender<(i32, Option<String>)>,
|
pub accept_tx: async_broadcast::Sender<(i32, Result<String, String>)>,
|
||||||
pub sessions_ref: Arc<DashMap<i32, StreamSession>>,
|
pub sessions_ref: Arc<DashMap<i32, StreamSession>>,
|
||||||
pub proxy: Arc<WebrtcProxy>,
|
pub proxy: Arc<WebrtcProxy>,
|
||||||
pub db: DatabaseConnection,
|
pub db: DatabaseConnection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Webrtc {
|
impl Webrtc {
|
||||||
@@ -40,7 +40,7 @@ impl Webrtc {
|
|||||||
request_id,
|
request_id,
|
||||||
stream_id, "stream key not found in DB, rejecting offer"
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
if let Err(ref e) = stream_key {
|
if let Err(ref e) = stream_key {
|
||||||
@@ -48,7 +48,7 @@ impl Webrtc {
|
|||||||
request_id,
|
request_id,
|
||||||
stream_id, "DB error looking up stream key: {:?}", e
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ impl Webrtc {
|
|||||||
Ok(sdp) => sdp,
|
Ok(sdp) => sdp,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!(request_id, stream_id, "malformed SDP offer: {:?}", 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;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -179,7 +179,10 @@ impl Webrtc {
|
|||||||
"no video codec negotiated — browser likely doesn't support {:?}; rejecting offer",
|
"no video codec negotiated — browser likely doesn't support {:?}; rejecting offer",
|
||||||
stream_codec
|
stream_codec
|
||||||
);
|
);
|
||||||
self.accept_tx.broadcast((request_id, None)).await.unwrap();
|
self.accept_tx
|
||||||
|
.broadcast((request_id, Err(format!("{:?}", stream_codec))))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +196,7 @@ impl Webrtc {
|
|||||||
|
|
||||||
debug!(request_id, "sending answer back");
|
debug!(request_id, "sending answer back");
|
||||||
self.accept_tx
|
self.accept_tx
|
||||||
.broadcast((request_id, Some(answer_sdp)))
|
.broadcast((request_id, Ok(answer_sdp)))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -310,8 +313,8 @@ impl Webrtc {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(_e) => {
|
||||||
error!("poll_output error (connection closing): {:?}", e);
|
// error!("poll_output error (connection closing): {:?}", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -487,6 +490,5 @@ impl Webrtc {
|
|||||||
{
|
{
|
||||||
warn!("RTP write error: {:?}", e);
|
warn!("RTP write error: {:?}", e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user