From 0661ea2026af2eaef6c4550d18ee32fb671c5951 Mon Sep 17 00:00:00 2001 From: euzu Date: Thu, 24 Apr 2025 18:34:56 +0200 Subject: [PATCH] multi-provider hls stream fix --- src/api/api_utils.rs | 12 +++--------- src/api/endpoints/hls_api.rs | 4 ++-- src/api/model/active_provider_manager.rs | 10 ++++++---- src/processing/parser/hls.rs | 2 +- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/api/api_utils.rs b/src/api/api_utils.rs index 5f38fc55f..ee9e035b2 100644 --- a/src/api/api_utils.rs +++ b/src/api/api_utils.rs @@ -472,7 +472,7 @@ fn is_throttled_stream(item_type: PlaylistItemType, throttle_kbps: usize) -> boo const SESSION_COOKIE_NAME: &str = "m3uflt_session="; fn create_delete_session_cookie() -> String { - format!("{SESSION_COOKIE_NAME}=; Max-Age=0; Path=/; HttpOnly") + format!("{SESSION_COOKIE_NAME}; Max-Age=0; Path=/; HttpOnly") } fn create_session_cookie(cookie: &str) -> String { @@ -822,7 +822,7 @@ pub fn redirect(url: &str) -> impl IntoResponse { pub fn is_seek_response( cluster: XtreamCluster, - virtual_id: u32, + _virtual_id: u32, req_headers: &HeaderMap, ) -> Option { // seek only for non-live streams @@ -830,19 +830,13 @@ pub fn is_seek_response( return None; } - // cookie needs to have virtual_id to identify that we have the same item - let cookie = read_session_cookie(req_headers)?; - if !cookie.starts_with(&format!("{virtual_id}:")) { - return None; - } - // seek requests contain range header let range = req_headers.get("range")?.to_str().ok()?; if range.starts_with("bytes=0-") { return None; } - Some(cookie) + Some(read_session_cookie(req_headers)?) } pub async fn check_force_provider(app_state: &AppState, virtual_id: u32, req_headers: &HeaderMap, user: &ProxyUserCredentials) -> (Option, UserConnectionPermission) { diff --git a/src/api/endpoints/hls_api.rs b/src/api/endpoints/hls_api.rs index 18caaa720..5ec3eba67 100644 --- a/src/api/endpoints/hls_api.rs +++ b/src/api/endpoints/hls_api.rs @@ -29,7 +29,7 @@ fn hls_response(hls_content: String, cookie: Option) -> impl IntoRespons .status(axum::http::StatusCode::OK) .header(axum::http::header::CONTENT_TYPE, "application/x-mpegurl"); if let Some(cookie) = cookie { - builder = builder.header(axum::http::header::COOKIE, cookie); + builder = builder.header(axum::http::header::SET_COOKIE, cookie); } builder.body(hls_content) .unwrap() @@ -62,7 +62,7 @@ pub(in crate::api) async fn handle_hls_stream_request(app_state: &Arc, None => (url, None, None), }, Some(provider) => match app_state.active_provider.force_exact_acquire_connection(&provider).await.get_provider_config() { - Some(provider_cfg) => create_stream_and_cookie(provider_cfg), + Some(provider_cfg) => create_stream_and_cookie(&provider_cfg), None => (url, None, None), }, }; diff --git a/src/api/model/active_provider_manager.rs b/src/api/model/active_provider_manager.rs index 7949f4d28..ccba3f387 100644 --- a/src/api/model/active_provider_manager.rs +++ b/src/api/model/active_provider_manager.rs @@ -21,12 +21,12 @@ impl ProviderConnectionGuard { } } } - pub fn get_provider_config(&self) -> Option<&Arc> { + pub fn get_provider_config(&self) -> Option> { match self.allocation { ProviderAllocation::Exhausted => None, ProviderAllocation::Available(ref cfg) | ProviderAllocation::GracePeriod(ref cfg) => { - Some(cfg) + Some(Arc::clone(cfg)) } } } @@ -488,7 +488,7 @@ impl MultiProviderLineup { let allocation = { let config = Self::get_next_provider_from_group(priority_group, false); if config.is_none() { - Self::get_next_provider_from_group(priority_group, false) + Self::get_next_provider_from_group(priority_group, true) } else { config } @@ -574,7 +574,9 @@ impl ActiveProviderManager { for group in &multi.providers { match group { ProviderPriorityGroup::SingleProviderGroup(config) => { - return Some((lineup, config)); + if config.name == name { + return Some((lineup, config)); + } } ProviderPriorityGroup::MultiProviderGroup(_, configs) => { for config in configs { diff --git a/src/processing/parser/hls.rs b/src/processing/parser/hls.rs index cf1db2918..801bef759 100644 --- a/src/processing/parser/hls.rs +++ b/src/processing/parser/hls.rs @@ -30,7 +30,7 @@ fn rewrite_hls_url(input: &str, replacement: &str) -> String { } fn rewrite_uri_attrib(line: &str, props: &RewriteHlsProps) -> String { - if let Some(caps) = CONSTANTS.re_memory_usage.captures(line) { + if let Some(caps) = CONSTANTS.re_hls_uri.captures(line) { let uri = &caps[1]; let target_url = &rewrite_hls_url(&props.hls_url, uri); if let Some(token) = create_token_for_provider(props.secret, props.virtual_id, &props.provider_name, target_url) {