mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-22 19:41:00 +00:00
net: webrtc/webrtchttp: Fix canceller usage
Commit 08b6251a
added the check to ensure only one canceller at a time for net/webrtc.
In `whipsink` and since `whipwebrtcsink` picked up the same implementation, there exists a
bug around the use of canceller. `whipsink` calls `wait_async` while passing the canceller
as an argument. The path `send_offer -> do_post -> parse_endpoint_response` results in the
canceller being replaced in each subsequent call to `wait_async`. Since `wait_async` call
does not ensure one canceller, with the async call the use of canceller/abort was subtly
broken. Similarly, for `whepsrc`.
We really don't need to use `wait_async` inside `do_post` for any `await` calls. If the
root future viz. `do_post` with `wait_async` is aborted, the child futures will be taken
care of.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1290>
This commit is contained in:
parent
d6616fed3f
commit
5b60ecbb18
4 changed files with 116 additions and 197 deletions
|
@ -124,14 +124,12 @@ impl Signaller {
|
||||||
async fn do_post(&self, offer: gst_webrtc::WebRTCSessionDescription, webrtcbin: &gst::Element) {
|
async fn do_post(&self, offer: gst_webrtc::WebRTCSessionDescription, webrtcbin: &gst::Element) {
|
||||||
let auth_token;
|
let auth_token;
|
||||||
let endpoint;
|
let endpoint;
|
||||||
let timeout;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
endpoint =
|
endpoint =
|
||||||
reqwest::Url::parse(settings.whip_endpoint.as_ref().unwrap().as_str()).unwrap();
|
reqwest::Url::parse(settings.whip_endpoint.as_ref().unwrap().as_str()).unwrap();
|
||||||
auth_token = settings.auth_token.clone();
|
auth_token = settings.auth_token.clone();
|
||||||
timeout = settings.timeout;
|
|
||||||
drop(settings);
|
drop(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,33 +172,19 @@ impl Signaller {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = wait_async(
|
let res = client
|
||||||
&self.canceller,
|
.request(reqwest::Method::POST, endpoint.clone())
|
||||||
client
|
.headers(headermap)
|
||||||
.request(reqwest::Method::POST, endpoint.clone())
|
.body(body)
|
||||||
.headers(headermap)
|
.send()
|
||||||
.body(body)
|
.await;
|
||||||
.send(),
|
|
||||||
timeout,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(r) => match r {
|
Ok(resp) => {
|
||||||
Ok(resp) => {
|
self.parse_endpoint_response(offer, resp, redirects, webrtcbin)
|
||||||
if let Err(e) = wait_async(
|
|
||||||
&self.canceller,
|
|
||||||
self.parse_endpoint_response(offer, resp, redirects, webrtcbin),
|
|
||||||
timeout,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
{
|
}
|
||||||
self.handle_future_error(e);
|
Err(err) => self.raise_error(err.to_string()),
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => self.raise_error(err.to_string()),
|
|
||||||
},
|
|
||||||
Err(err) => self.handle_future_error(err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +198,6 @@ impl Signaller {
|
||||||
gst::debug!(CAT, imp: self, "Parsing endpoint response");
|
gst::debug!(CAT, imp: self, "Parsing endpoint response");
|
||||||
|
|
||||||
let endpoint;
|
let endpoint;
|
||||||
let timeout;
|
|
||||||
let use_link_headers;
|
let use_link_headers;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -222,7 +205,6 @@ impl Signaller {
|
||||||
endpoint =
|
endpoint =
|
||||||
reqwest::Url::parse(settings.whip_endpoint.as_ref().unwrap().as_str()).unwrap();
|
reqwest::Url::parse(settings.whip_endpoint.as_ref().unwrap().as_str()).unwrap();
|
||||||
use_link_headers = settings.use_link_headers;
|
use_link_headers = settings.use_link_headers;
|
||||||
timeout = settings.timeout;
|
|
||||||
drop(settings);
|
drop(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,26 +270,21 @@ impl Signaller {
|
||||||
drop(state);
|
drop(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
match wait_async(&self.canceller, resp.bytes(), timeout).await {
|
match resp.bytes().await {
|
||||||
Ok(res) => match res {
|
Ok(ans_bytes) => match gst_sdp::SDPMessage::parse_buffer(&ans_bytes) {
|
||||||
Ok(ans_bytes) => match gst_sdp::SDPMessage::parse_buffer(&ans_bytes) {
|
Ok(ans_sdp) => {
|
||||||
Ok(ans_sdp) => {
|
let answer = gst_webrtc::WebRTCSessionDescription::new(
|
||||||
let answer = gst_webrtc::WebRTCSessionDescription::new(
|
gst_webrtc::WebRTCSDPType::Answer,
|
||||||
gst_webrtc::WebRTCSDPType::Answer,
|
ans_sdp,
|
||||||
ans_sdp,
|
);
|
||||||
);
|
self.obj()
|
||||||
self.obj().emit_by_name::<()>(
|
.emit_by_name::<()>("session-description", &[&"unique", &answer]);
|
||||||
"session-description",
|
}
|
||||||
&[&"unique", &answer],
|
Err(err) => {
|
||||||
);
|
self.raise_error(format!("Could not parse answer SDP: {err}"));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
|
||||||
self.raise_error(format!("Could not parse answer SDP: {err}"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(err) => self.raise_error(err.to_string()),
|
|
||||||
},
|
},
|
||||||
Err(err) => self.handle_future_error(err),
|
Err(err) => self.raise_error(err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,12 +324,7 @@ impl Signaller {
|
||||||
redirect_url.as_str()
|
redirect_url.as_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(err) =
|
self.do_post(offer, webrtcbin).await
|
||||||
wait_async(&self.canceller, self.do_post(offer, webrtcbin), timeout)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
self.handle_future_error(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(e) => self.raise_error(e.to_string()),
|
Err(e) => self.raise_error(e.to_string()),
|
||||||
}
|
}
|
||||||
|
@ -362,16 +334,14 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
s => {
|
s => {
|
||||||
match wait_async(&self.canceller, resp.bytes(), timeout).await {
|
match resp.bytes().await {
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
let res = r
|
let res = r.escape_ascii().to_string();
|
||||||
.map(|x| x.escape_ascii().to_string())
|
|
||||||
.unwrap_or_else(|_| "(no further details)".to_string());
|
|
||||||
|
|
||||||
// FIXME: Check and handle 'Retry-After' header in case of server error
|
// FIXME: Check and handle 'Retry-After' header in case of server error
|
||||||
self.raise_error(format!("Unexpected response: {} - {}", s.as_str(), res));
|
self.raise_error(format!("Unexpected response: {} - {}", s.as_str(), res));
|
||||||
}
|
}
|
||||||
Err(err) => self.handle_future_error(err),
|
Err(err) => self.raise_error(err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,12 @@ where
|
||||||
let (abort_handle, abort_registration) = future::AbortHandle::new_pair();
|
let (abort_handle, abort_registration) = future::AbortHandle::new_pair();
|
||||||
{
|
{
|
||||||
let mut canceller_guard = canceller.lock().unwrap();
|
let mut canceller_guard = canceller.lock().unwrap();
|
||||||
|
if canceller_guard.is_some() {
|
||||||
|
return Err(WaitError::FutureError(gst::error_msg!(
|
||||||
|
gst::ResourceError::Failed,
|
||||||
|
["Old Canceller should not exist"]
|
||||||
|
)));
|
||||||
|
}
|
||||||
canceller_guard.replace(abort_handle);
|
canceller_guard.replace(abort_handle);
|
||||||
drop(canceller_guard);
|
drop(canceller_guard);
|
||||||
}
|
}
|
||||||
|
|
|
@ -626,7 +626,6 @@ impl WhepSrc {
|
||||||
redirects: u8,
|
redirects: u8,
|
||||||
) {
|
) {
|
||||||
let endpoint;
|
let endpoint;
|
||||||
let timeout;
|
|
||||||
let use_link_headers;
|
let use_link_headers;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -634,7 +633,6 @@ impl WhepSrc {
|
||||||
endpoint =
|
endpoint =
|
||||||
reqwest::Url::parse(settings.whep_endpoint.as_ref().unwrap().as_str()).unwrap();
|
reqwest::Url::parse(settings.whep_endpoint.as_ref().unwrap().as_str()).unwrap();
|
||||||
use_link_headers = settings.use_link_headers;
|
use_link_headers = settings.use_link_headers;
|
||||||
timeout = settings.timeout;
|
|
||||||
drop(settings);
|
drop(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,29 +690,26 @@ impl WhepSrc {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match wait_async(&self.canceller, resp.bytes(), timeout).await {
|
match resp.bytes().await {
|
||||||
Ok(res) => match res {
|
Ok(ans_bytes) => {
|
||||||
Ok(ans_bytes) => {
|
let mut state = self.state.lock().unwrap();
|
||||||
let mut state = self.state.lock().unwrap();
|
*state = match *state {
|
||||||
*state = match *state {
|
State::Post { redirects: _r } => State::Running {
|
||||||
State::Post { redirects: _r } => State::Running {
|
whep_resource: url.to_string(),
|
||||||
whep_resource: url.to_string(),
|
},
|
||||||
},
|
_ => {
|
||||||
_ => {
|
self.raise_error(
|
||||||
self.raise_error(
|
gst::ResourceError::Failed,
|
||||||
gst::ResourceError::Failed,
|
"Expected to be in POST state".to_string(),
|
||||||
"Expected to be in POST state".to_string(),
|
);
|
||||||
);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
};
|
||||||
};
|
drop(state);
|
||||||
drop(state);
|
|
||||||
|
|
||||||
self.sdp_message_parse(ans_bytes)
|
self.sdp_message_parse(ans_bytes)
|
||||||
}
|
}
|
||||||
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
||||||
},
|
|
||||||
Err(err) => self.handle_future_error(err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,11 +748,7 @@ impl WhepSrc {
|
||||||
redirect_url.as_str()
|
redirect_url.as_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(err) =
|
self.do_post(sess_desc).await
|
||||||
wait_async(&self.canceller, self.do_post(sess_desc), timeout).await
|
|
||||||
{
|
|
||||||
self.handle_future_error(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(e) => self.raise_error(gst::ResourceError::Failed, e.to_string()),
|
Err(e) => self.raise_error(gst::ResourceError::Failed, e.to_string()),
|
||||||
}
|
}
|
||||||
|
@ -770,11 +761,9 @@ impl WhepSrc {
|
||||||
}
|
}
|
||||||
|
|
||||||
s => {
|
s => {
|
||||||
match wait_async(&self.canceller, resp.bytes(), timeout).await {
|
match resp.bytes().await {
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
let res = r
|
let res = r.escape_ascii().to_string();
|
||||||
.map(|x| x.escape_ascii().to_string())
|
|
||||||
.unwrap_or_else(|_| "(no further details)".to_string());
|
|
||||||
|
|
||||||
// FIXME: Check and handle 'Retry-After' header in case of server error
|
// FIXME: Check and handle 'Retry-After' header in case of server error
|
||||||
self.raise_error(
|
self.raise_error(
|
||||||
|
@ -782,7 +771,7 @@ impl WhepSrc {
|
||||||
format!("Unexpected response: {} - {}", s.as_str(), res),
|
format!("Unexpected response: {} - {}", s.as_str(), res),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(err) => self.handle_future_error(err),
|
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -944,14 +933,12 @@ impl WhepSrc {
|
||||||
async fn do_post(&self, offer: WebRTCSessionDescription) {
|
async fn do_post(&self, offer: WebRTCSessionDescription) {
|
||||||
let auth_token;
|
let auth_token;
|
||||||
let endpoint;
|
let endpoint;
|
||||||
let timeout;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
endpoint =
|
endpoint =
|
||||||
reqwest::Url::parse(settings.whep_endpoint.as_ref().unwrap().as_str()).unwrap();
|
reqwest::Url::parse(settings.whep_endpoint.as_ref().unwrap().as_str()).unwrap();
|
||||||
auth_token = settings.auth_token.clone();
|
auth_token = settings.auth_token.clone();
|
||||||
timeout = settings.timeout;
|
|
||||||
drop(settings);
|
drop(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,51 +969,37 @@ impl WhepSrc {
|
||||||
endpoint.as_str()
|
endpoint.as_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
let res = wait_async(
|
let resp = self
|
||||||
&self.canceller,
|
.client
|
||||||
self.client
|
.request(reqwest::Method::POST, endpoint.clone())
|
||||||
.request(reqwest::Method::POST, endpoint.clone())
|
.headers(headermap)
|
||||||
.headers(headermap)
|
.body(body)
|
||||||
.body(body)
|
.send()
|
||||||
.send(),
|
.await;
|
||||||
timeout,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match res {
|
match resp {
|
||||||
Ok(resp) => match resp {
|
Ok(r) => {
|
||||||
Ok(r) => {
|
#[allow(unused_mut)]
|
||||||
#[allow(unused_mut)]
|
let mut redirects;
|
||||||
let mut redirects;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
redirects = match *state {
|
redirects = match *state {
|
||||||
State::Post { redirects } => redirects,
|
State::Post { redirects } => redirects,
|
||||||
_ => {
|
_ => {
|
||||||
self.raise_error(
|
self.raise_error(
|
||||||
gst::ResourceError::Failed,
|
gst::ResourceError::Failed,
|
||||||
"Trying to do POST in unexpected state".to_string(),
|
"Trying to do POST in unexpected state".to_string(),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
drop(state);
|
drop(state);
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(e) = wait_async(
|
|
||||||
&self.canceller,
|
|
||||||
self.parse_endpoint_response(offer, r, redirects),
|
|
||||||
timeout,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
self.handle_future_error(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
|
||||||
},
|
self.parse_endpoint_response(offer, r, redirects).await
|
||||||
Err(err) => self.handle_future_error(err),
|
}
|
||||||
|
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -565,14 +565,12 @@ impl WhipSink {
|
||||||
async fn do_post(&self, offer: gst_webrtc::WebRTCSessionDescription) {
|
async fn do_post(&self, offer: gst_webrtc::WebRTCSessionDescription) {
|
||||||
let auth_token;
|
let auth_token;
|
||||||
let endpoint;
|
let endpoint;
|
||||||
let timeout;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
endpoint =
|
endpoint =
|
||||||
reqwest::Url::parse(settings.whip_endpoint.as_ref().unwrap().as_str()).unwrap();
|
reqwest::Url::parse(settings.whip_endpoint.as_ref().unwrap().as_str()).unwrap();
|
||||||
auth_token = settings.auth_token.clone();
|
auth_token = settings.auth_token.clone();
|
||||||
timeout = settings.timeout;
|
|
||||||
drop(settings);
|
drop(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,33 +616,16 @@ impl WhipSink {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = wait_async(
|
let res = client
|
||||||
&self.canceller,
|
.request(reqwest::Method::POST, endpoint.clone())
|
||||||
client
|
.headers(headermap)
|
||||||
.request(reqwest::Method::POST, endpoint.clone())
|
.body(body)
|
||||||
.headers(headermap)
|
.send()
|
||||||
.body(body)
|
.await;
|
||||||
.send(),
|
|
||||||
timeout,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(r) => match r {
|
Ok(resp) => self.parse_endpoint_response(offer, resp, redirects).await,
|
||||||
Ok(resp) => {
|
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
||||||
if let Err(e) = wait_async(
|
|
||||||
&self.canceller,
|
|
||||||
self.parse_endpoint_response(offer, resp, redirects),
|
|
||||||
timeout,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
self.handle_future_error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
|
||||||
},
|
|
||||||
Err(err) => self.handle_future_error(err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,7 +636,6 @@ impl WhipSink {
|
||||||
redirects: u8,
|
redirects: u8,
|
||||||
) {
|
) {
|
||||||
let endpoint;
|
let endpoint;
|
||||||
let timeout;
|
|
||||||
let use_link_headers;
|
let use_link_headers;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -663,7 +643,6 @@ impl WhipSink {
|
||||||
endpoint =
|
endpoint =
|
||||||
reqwest::Url::parse(settings.whip_endpoint.as_ref().unwrap().as_str()).unwrap();
|
reqwest::Url::parse(settings.whip_endpoint.as_ref().unwrap().as_str()).unwrap();
|
||||||
use_link_headers = settings.use_link_headers;
|
use_link_headers = settings.use_link_headers;
|
||||||
timeout = settings.timeout;
|
|
||||||
drop(settings);
|
drop(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,29 +716,26 @@ impl WhipSink {
|
||||||
drop(state);
|
drop(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
match wait_async(&self.canceller, resp.bytes(), timeout).await {
|
match resp.bytes().await {
|
||||||
Ok(res) => match res {
|
Ok(ans_bytes) => match sdp_message::SDPMessage::parse_buffer(&ans_bytes) {
|
||||||
Ok(ans_bytes) => match sdp_message::SDPMessage::parse_buffer(&ans_bytes) {
|
Ok(ans_sdp) => {
|
||||||
Ok(ans_sdp) => {
|
let answer = gst_webrtc::WebRTCSessionDescription::new(
|
||||||
let answer = gst_webrtc::WebRTCSessionDescription::new(
|
gst_webrtc::WebRTCSDPType::Answer,
|
||||||
gst_webrtc::WebRTCSDPType::Answer,
|
ans_sdp,
|
||||||
ans_sdp,
|
);
|
||||||
);
|
self.webrtcbin.emit_by_name::<()>(
|
||||||
self.webrtcbin.emit_by_name::<()>(
|
"set-remote-description",
|
||||||
"set-remote-description",
|
&[&answer, &None::<gst::Promise>],
|
||||||
&[&answer, &None::<gst::Promise>],
|
);
|
||||||
);
|
}
|
||||||
}
|
Err(err) => {
|
||||||
Err(err) => {
|
self.raise_error(
|
||||||
self.raise_error(
|
gst::ResourceError::Failed,
|
||||||
gst::ResourceError::Failed,
|
format!("Could not parse answer SDP: {err}"),
|
||||||
format!("Could not parse answer SDP: {err}"),
|
);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
|
||||||
},
|
},
|
||||||
Err(err) => self.handle_future_error(err),
|
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,11 +774,7 @@ impl WhipSink {
|
||||||
redirect_url.as_str()
|
redirect_url.as_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(err) =
|
self.do_post(offer).await
|
||||||
wait_async(&self.canceller, self.do_post(offer), timeout).await
|
|
||||||
{
|
|
||||||
self.handle_future_error(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(e) => self.raise_error(gst::ResourceError::Failed, e.to_string()),
|
Err(e) => self.raise_error(gst::ResourceError::Failed, e.to_string()),
|
||||||
}
|
}
|
||||||
|
@ -815,11 +787,9 @@ impl WhipSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
s => {
|
s => {
|
||||||
match wait_async(&self.canceller, resp.bytes(), timeout).await {
|
match resp.bytes().await {
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
let res = r
|
let res = r.escape_ascii().to_string();
|
||||||
.map(|x| x.escape_ascii().to_string())
|
|
||||||
.unwrap_or_else(|_| "(no further details)".to_string());
|
|
||||||
|
|
||||||
// FIXME: Check and handle 'Retry-After' header in case of server error
|
// FIXME: Check and handle 'Retry-After' header in case of server error
|
||||||
self.raise_error(
|
self.raise_error(
|
||||||
|
@ -827,7 +797,7 @@ impl WhipSink {
|
||||||
format!("Unexpected response: {} - {}", s.as_str(), res),
|
format!("Unexpected response: {} - {}", s.as_str(), res),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(err) => self.handle_future_error(err),
|
Err(err) => self.raise_error(gst::ResourceError::Failed, err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue