mirror of
https://github.com/euzu/tuliprox.git
synced 2026-10-31 03:02:24 +01:00
stream table ip fixed
This commit is contained in:
@@ -123,6 +123,7 @@ pub use try_option_bad_request;
|
||||
pub use try_result_bad_request;
|
||||
pub use try_result_not_found;
|
||||
pub use try_unwrap_body;
|
||||
use crate::auth::Fingerprint;
|
||||
|
||||
pub fn get_server_time() -> String {
|
||||
chrono::offset::Local::now()
|
||||
@@ -382,7 +383,7 @@ struct StreamingStrategy {
|
||||
async fn resolve_streaming_strategy(
|
||||
app_state: &AppState,
|
||||
stream_url: &str,
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
input: &ConfigInput,
|
||||
force_provider: Option<&str>,
|
||||
) -> StreamingStrategy {
|
||||
@@ -391,13 +392,13 @@ async fn resolve_streaming_strategy(
|
||||
Some(provider) => {
|
||||
app_state
|
||||
.active_provider
|
||||
.force_exact_acquire_connection(provider, addr)
|
||||
.force_exact_acquire_connection(provider, &fingerprint.addr)
|
||||
.await
|
||||
}
|
||||
None => {
|
||||
app_state
|
||||
.active_provider
|
||||
.acquire_connection(&input.name, addr)
|
||||
.acquire_connection(&input.name, &fingerprint.addr)
|
||||
.await
|
||||
}
|
||||
};
|
||||
@@ -461,7 +462,7 @@ async fn create_stream_response_details(
|
||||
app_state: &AppState,
|
||||
stream_options: &StreamOptions,
|
||||
stream_url: &str,
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
req_headers: &HeaderMap,
|
||||
input: &ConfigInput,
|
||||
item_type: PlaylistItemType,
|
||||
@@ -469,7 +470,7 @@ async fn create_stream_response_details(
|
||||
connection_permission: UserConnectionPermission,
|
||||
force_provider: Option<&str>,
|
||||
) -> StreamDetails {
|
||||
let mut streaming_strategy = resolve_streaming_strategy(app_state, stream_url, addr, input, force_provider).await;
|
||||
let mut streaming_strategy = resolve_streaming_strategy(app_state, stream_url, fingerprint, input, force_provider).await;
|
||||
let config_grace_period_millis = app_state
|
||||
.app_config
|
||||
.config
|
||||
@@ -736,7 +737,7 @@ fn prepare_body_stream(
|
||||
|
||||
/// # Panics
|
||||
pub async fn force_provider_stream_response(
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
app_state: &AppState,
|
||||
user_session: &UserSession,
|
||||
mut stream_channel: StreamChannel,
|
||||
@@ -753,7 +754,7 @@ pub async fn force_provider_stream_response(
|
||||
app_state,
|
||||
&stream_options,
|
||||
&user_session.stream_url,
|
||||
addr,
|
||||
fingerprint,
|
||||
req_headers,
|
||||
input,
|
||||
item_type,
|
||||
@@ -770,11 +771,11 @@ pub async fn force_provider_stream_response(
|
||||
.map(|(h, sc, url)| (h.clone(), *sc, url.clone()));
|
||||
app_state
|
||||
.active_users
|
||||
.update_session_addr(&user.username, &user_session.token, addr)
|
||||
.update_session_addr(&user.username, &user_session.token, &fingerprint.addr)
|
||||
.await;
|
||||
stream_channel.shared = share_stream;
|
||||
let stream =
|
||||
ActiveClientStream::new(stream_details, app_state, user, connection_permission, addr, stream_channel, req_headers)
|
||||
ActiveClientStream::new(stream_details, app_state, user, connection_permission, fingerprint, stream_channel, req_headers)
|
||||
.await;
|
||||
|
||||
let (status_code, header_map) =
|
||||
@@ -809,7 +810,7 @@ pub async fn force_provider_stream_response(
|
||||
/// # Panics
|
||||
#[allow(clippy::too_many_arguments, clippy::too_many_lines)]
|
||||
pub async fn stream_response(
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
app_state: &AppState,
|
||||
session_token: &str,
|
||||
mut stream_channel: StreamChannel,
|
||||
@@ -838,7 +839,7 @@ pub async fn stream_response(
|
||||
let share_stream = is_stream_share_enabled(item_type, target);
|
||||
if share_stream {
|
||||
if let Some(value) =
|
||||
shared_stream_response(app_state, stream_url, addr, user, connection_permission, stream_channel.clone(), req_headers).await
|
||||
shared_stream_response(app_state, stream_url, fingerprint, user, connection_permission, stream_channel.clone(), req_headers).await
|
||||
{
|
||||
return value.into_response();
|
||||
}
|
||||
@@ -849,7 +850,7 @@ pub async fn stream_response(
|
||||
app_state,
|
||||
&stream_options,
|
||||
stream_url,
|
||||
addr,
|
||||
fingerprint,
|
||||
req_headers,
|
||||
input,
|
||||
item_type,
|
||||
@@ -873,7 +874,7 @@ pub async fn stream_response(
|
||||
};
|
||||
stream_channel.shared = share_stream;
|
||||
let stream =
|
||||
ActiveClientStream::new(stream_details, app_state, user, connection_permission, addr, stream_channel, req_headers)
|
||||
ActiveClientStream::new(stream_details, app_state, user, connection_permission, fingerprint, stream_channel, req_headers)
|
||||
.await;
|
||||
let stream_resp = if share_stream {
|
||||
debug_if_enabled!(
|
||||
@@ -889,7 +890,7 @@ pub async fn stream_response(
|
||||
app_state,
|
||||
stream_url,
|
||||
stream,
|
||||
Some(addr),
|
||||
Some(&fingerprint.addr),
|
||||
shared_headers,
|
||||
stream_options.buffer_size,
|
||||
provider_guard,
|
||||
@@ -952,7 +953,7 @@ pub async fn stream_response(
|
||||
virtual_id,
|
||||
&provider,
|
||||
&session_url,
|
||||
addr,
|
||||
&fingerprint.addr,
|
||||
connection_permission,
|
||||
)
|
||||
.await;
|
||||
@@ -984,14 +985,14 @@ fn get_stream_throttle(app_state: &AppState) -> u64 {
|
||||
async fn shared_stream_response(
|
||||
app_state: &AppState,
|
||||
stream_url: &str,
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
user: &ProxyUserCredentials,
|
||||
connect_permission: UserConnectionPermission,
|
||||
mut stream_channel: StreamChannel,
|
||||
req_headers: &HeaderMap,
|
||||
) -> Option<impl IntoResponse> {
|
||||
if let Some((stream, provider)) =
|
||||
SharedStreamManager::subscribe_shared_stream(app_state, stream_url, Some(addr)).await
|
||||
SharedStreamManager::subscribe_shared_stream(app_state, stream_url, Some(&fingerprint.addr)).await
|
||||
{
|
||||
debug_if_enabled!(
|
||||
"Using shared stream {}",
|
||||
@@ -1010,7 +1011,7 @@ async fn shared_stream_response(
|
||||
stream_details.provider_name = provider;
|
||||
stream_channel.shared = true;
|
||||
let stream =
|
||||
ActiveClientStream::new(stream_details, app_state, user, connect_permission, addr, stream_channel, req_headers)
|
||||
ActiveClientStream::new(stream_details, app_state, user, connect_permission, fingerprint, stream_channel, req_headers)
|
||||
.await
|
||||
.boxed();
|
||||
let mut response = axum::response::Response::builder().status(status_code);
|
||||
@@ -1326,6 +1327,6 @@ pub fn json_or_bin_response<T: Serialize>(accept: Option<&String>, data: &T) ->
|
||||
json_response(data).into_response()
|
||||
}
|
||||
|
||||
pub fn create_fingerprint(fingerprint: &str, username: &str, virtual_id: u32) -> String {
|
||||
pub fn create_session_fingerprint(fingerprint: &str, username: &str, virtual_id: u32) -> String {
|
||||
format!("{fingerprint}|{username}|{virtual_id}")
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::api::api_utils::{create_fingerprint, try_unwrap_body};
|
||||
use crate::api::api_utils::{create_session_fingerprint, try_unwrap_body};
|
||||
use crate::api::api_utils::{
|
||||
force_provider_stream_response, get_stream_alternative_url, is_seek_request,
|
||||
};
|
||||
@@ -41,8 +41,7 @@ fn hls_response(hls_content: String) -> impl IntoResponse + Send {
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(in crate::api) async fn handle_hls_stream_request(
|
||||
fingerprint: &str,
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
app_state: &Arc<AppState>,
|
||||
user: &ProxyUserCredentials,
|
||||
user_session: Option<&UserSession>,
|
||||
@@ -59,7 +58,7 @@ pub(in crate::api) async fn handle_hls_stream_request(
|
||||
Some(session) => {
|
||||
match app_state
|
||||
.active_provider
|
||||
.force_exact_acquire_connection(&session.provider, addr)
|
||||
.force_exact_acquire_connection(&session.provider, &fingerprint.addr)
|
||||
.await
|
||||
.get_provider_config()
|
||||
{
|
||||
@@ -78,14 +77,14 @@ pub(in crate::api) async fn handle_hls_stream_request(
|
||||
{
|
||||
Some(provider_cfg) => {
|
||||
let stream_url = get_stream_alternative_url(&url, input, &provider_cfg);
|
||||
let user_session_token = create_fingerprint(fingerprint, &user.username, virtual_id);
|
||||
let user_session_token = create_session_fingerprint(&fingerprint.key, &user.username, virtual_id);
|
||||
let session_token = app_state.active_users.create_user_session(
|
||||
user,
|
||||
&user_session_token,
|
||||
virtual_id,
|
||||
&provider_cfg.name,
|
||||
&stream_url,
|
||||
addr,
|
||||
&fingerprint.addr,
|
||||
connection_permission,
|
||||
).await;
|
||||
(stream_url, Some(session_token))
|
||||
@@ -188,7 +187,7 @@ async fn resolve_stream_channel(
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
async fn hls_api_stream(
|
||||
Fingerprint(fingerprint, addr): Fingerprint,
|
||||
fingerprint: Fingerprint,
|
||||
req_headers: axum::http::HeaderMap,
|
||||
axum::extract::Path(params): axum::extract::Path<HlsApiPathParams>,
|
||||
axum::extract::State(app_state): axum::extract::State<Arc<AppState>>,
|
||||
@@ -218,7 +217,7 @@ async fn hls_api_stream(
|
||||
)
|
||||
);
|
||||
|
||||
let user_session_token = create_fingerprint(&fingerprint, &user.username, virtual_id);
|
||||
let user_session_token = create_session_fingerprint(&fingerprint.key, &user.username, virtual_id);
|
||||
let mut user_session = app_state
|
||||
.active_users
|
||||
.get_and_update_user_session(&user.username, &user_session_token).await;
|
||||
@@ -258,7 +257,7 @@ async fn hls_api_stream(
|
||||
if is_seek_request(stream_channel.cluster, &req_headers).await {
|
||||
// partial request means we are in reverse proxy mode, seek happened
|
||||
return force_provider_stream_response(
|
||||
&addr,
|
||||
&fingerprint,
|
||||
&app_state,
|
||||
session,
|
||||
stream_channel,
|
||||
@@ -285,7 +284,6 @@ async fn hls_api_stream(
|
||||
if is_hls_url(&session.stream_url) {
|
||||
return handle_hls_stream_request(
|
||||
&fingerprint,
|
||||
&addr,
|
||||
&app_state,
|
||||
&user,
|
||||
Some(session),
|
||||
@@ -301,7 +299,7 @@ async fn hls_api_stream(
|
||||
|
||||
let stream_channel = resolve_stream_channel(&app_state, &target, virtual_id, &hls_url).await;
|
||||
force_provider_stream_response(
|
||||
&addr,
|
||||
&fingerprint,
|
||||
&app_state,
|
||||
session,
|
||||
stream_channel,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::api::api_utils::{create_fingerprint, try_unwrap_body};
|
||||
use crate::api::api_utils::{create_session_fingerprint, try_unwrap_body};
|
||||
use crate::api::api_utils::{
|
||||
force_provider_stream_response, get_user_target, get_user_target_by_credentials,
|
||||
is_seek_request, redirect, redirect_response, resource_response, separate_number_and_remainder,
|
||||
@@ -72,8 +72,7 @@ async fn m3u_api_post(
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
async fn m3u_api_stream(
|
||||
fingerprint: &str,
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
req_headers: &axum::http::HeaderMap,
|
||||
app_state: &Arc<AppState>,
|
||||
api_req: &UserApiRequest,
|
||||
@@ -124,7 +123,7 @@ async fn m3u_api_stream(
|
||||
);
|
||||
let cluster = XtreamCluster::try_from(pli.item_type).unwrap_or(XtreamCluster::Live);
|
||||
|
||||
let session_key = create_fingerprint(fingerprint, &user.username, virtual_id);
|
||||
let session_key = create_session_fingerprint(&fingerprint.key, &user.username, virtual_id);
|
||||
let user_session = app_state
|
||||
.active_users
|
||||
.get_and_update_user_session(&user.username, &session_key).await;
|
||||
@@ -152,7 +151,7 @@ async fn m3u_api_stream(
|
||||
if session.virtual_id == virtual_id && is_seek_request(cluster, req_headers).await {
|
||||
// partial request means we are in reverse proxy mode, seek happened
|
||||
return force_provider_stream_response(
|
||||
addr,
|
||||
fingerprint,
|
||||
app_state,
|
||||
session,
|
||||
pli.to_stream_channel(),
|
||||
@@ -208,7 +207,6 @@ async fn m3u_api_stream(
|
||||
if is_hls_request {
|
||||
return handle_hls_stream_request(
|
||||
fingerprint,
|
||||
addr,
|
||||
app_state,
|
||||
&user,
|
||||
user_session.as_ref(),
|
||||
@@ -223,7 +221,7 @@ async fn m3u_api_stream(
|
||||
}
|
||||
|
||||
stream_response(
|
||||
addr,
|
||||
fingerprint,
|
||||
app_state,
|
||||
&session_key,
|
||||
pli.to_stream_channel(),
|
||||
@@ -302,7 +300,7 @@ async fn m3u_api_resource(
|
||||
macro_rules! create_m3u_api_stream {
|
||||
($fn_name:ident, $context:expr) => {
|
||||
async fn $fn_name(
|
||||
Fingerprint(fingerprint, addr): Fingerprint,
|
||||
fingerprint: Fingerprint,
|
||||
req_headers: axum::http::HeaderMap,
|
||||
axum::extract::Query(api_req): axum::extract::Query<UserApiRequest>,
|
||||
axum::extract::Path((username, password, stream_id)): axum::extract::Path<(
|
||||
@@ -315,7 +313,6 @@ macro_rules! create_m3u_api_stream {
|
||||
) -> impl IntoResponse + Send {
|
||||
m3u_api_stream(
|
||||
&fingerprint,
|
||||
&addr,
|
||||
&req_headers,
|
||||
&app_state,
|
||||
&api_req,
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::auth::validator_admin;
|
||||
use crate::utils::ip_checker::get_ips;
|
||||
use crate::{VERSION};
|
||||
use axum::response::IntoResponse;
|
||||
use shared::model::{InputFetchMethod, IpCheckDto, StatusCheck};
|
||||
use shared::model::{default_geoip_url, InputFetchMethod, IpCheckDto, StatusCheck};
|
||||
use shared::utils::{concat_path_leading_slash};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::io::{Cursor};
|
||||
@@ -80,8 +80,9 @@ async fn geoip_update(axum::extract::State(app_state): axum::extract::State<Arc<
|
||||
let geoip_db_path = &*get_geoip_path(&config.working_dir);
|
||||
let _file_lock = app_state.app_config.file_locks.write_lock(geoip_db_path);
|
||||
|
||||
let url = if geoip.url.trim().is_empty() { default_geoip_url() } else { geoip.url.clone() };
|
||||
let input_source = InputSource {
|
||||
url: geoip.url.clone(),
|
||||
url,
|
||||
username: None,
|
||||
password: None,
|
||||
method: InputFetchMethod::GET,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// https://github.com/tellytv/go.xtream-codes/blob/master/structs.go
|
||||
|
||||
use crate::api::api_utils;
|
||||
use crate::api::api_utils::{create_fingerprint, try_unwrap_body};
|
||||
use crate::api::api_utils::{create_session_fingerprint, try_unwrap_body};
|
||||
use crate::api::api_utils::{
|
||||
force_provider_stream_response, get_user_target, get_user_target_by_credentials,
|
||||
is_seek_request, redirect_response, resource_response, separate_number_and_remainder,
|
||||
@@ -211,8 +211,7 @@ async fn get_user_info(user: &ProxyUserCredentials, app_state: &AppState) -> Xtr
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
async fn xtream_player_api_stream(
|
||||
fingerprint: &str,
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
req_headers: &HeaderMap,
|
||||
app_state: &Arc<AppState>,
|
||||
api_req: &UserApiRequest,
|
||||
@@ -269,7 +268,7 @@ async fn xtream_player_api_stream(
|
||||
(pli.xtream_cluster, pli.item_type)
|
||||
};
|
||||
|
||||
let session_key = create_fingerprint(fingerprint, &user.username, virtual_id);
|
||||
let session_key = create_session_fingerprint(&fingerprint.key, &user.username, virtual_id);
|
||||
let user_session = app_state
|
||||
.active_users
|
||||
.get_and_update_user_session(&user.username, &session_key).await;
|
||||
@@ -295,13 +294,16 @@ async fn xtream_player_api_stream(
|
||||
.into_response();
|
||||
}
|
||||
|
||||
let mut stream_channel = pli.to_stream_channel();
|
||||
stream_channel.item_type = item_type;
|
||||
|
||||
if session.virtual_id == virtual_id && is_seek_request(cluster, req_headers).await {
|
||||
// partial request means we are in reverse proxy mode, seek happened
|
||||
return force_provider_stream_response(
|
||||
addr,
|
||||
fingerprint,
|
||||
app_state,
|
||||
session,
|
||||
pli.to_stream_channel(),
|
||||
stream_channel,
|
||||
req_headers,
|
||||
&input,
|
||||
&user,
|
||||
@@ -369,7 +371,6 @@ async fn xtream_player_api_stream(
|
||||
if is_hls_request {
|
||||
return handle_hls_stream_request(
|
||||
fingerprint,
|
||||
addr,
|
||||
app_state,
|
||||
&user,
|
||||
user_session.as_ref(),
|
||||
@@ -383,11 +384,14 @@ async fn xtream_player_api_stream(
|
||||
.into_response();
|
||||
}
|
||||
|
||||
let mut stream_channel = pli.to_stream_channel();
|
||||
stream_channel.item_type = item_type;
|
||||
|
||||
stream_response(
|
||||
addr,
|
||||
fingerprint,
|
||||
app_state,
|
||||
session_key.as_str(),
|
||||
pli.to_stream_channel(),
|
||||
stream_channel,
|
||||
&stream_url,
|
||||
req_headers,
|
||||
&input,
|
||||
@@ -402,8 +406,7 @@ async fn xtream_player_api_stream(
|
||||
#[allow(clippy::too_many_lines)]
|
||||
// Used by webui
|
||||
async fn xtream_player_api_stream_with_token(
|
||||
fingerprint: &str,
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
req_headers: &HeaderMap,
|
||||
app_state: &Arc<AppState>,
|
||||
target_id: u16,
|
||||
@@ -439,7 +442,7 @@ async fn xtream_player_api_stream_with_token(
|
||||
)
|
||||
);
|
||||
|
||||
let session_key = create_fingerprint(fingerprint, "webui", virtual_id);
|
||||
let session_key = create_session_fingerprint(&fingerprint.key, "webui", virtual_id);
|
||||
|
||||
let is_hls_request =
|
||||
pli.item_type == PlaylistItemType::LiveHls || stream_ext.as_deref() == Some(HLS_EXT);
|
||||
@@ -472,7 +475,6 @@ async fn xtream_player_api_stream_with_token(
|
||||
if is_hls_request {
|
||||
return handle_hls_stream_request(
|
||||
fingerprint,
|
||||
addr,
|
||||
app_state,
|
||||
&user,
|
||||
None,
|
||||
@@ -516,7 +518,7 @@ async fn xtream_player_api_stream_with_token(
|
||||
sanitize_sensitive_info(&stream_url)
|
||||
);
|
||||
stream_response(
|
||||
addr,
|
||||
fingerprint,
|
||||
app_state,
|
||||
session_key.as_str(),
|
||||
pli.to_stream_channel(),
|
||||
@@ -770,7 +772,7 @@ async fn xtream_player_api_resource(
|
||||
macro_rules! create_xtream_player_api_stream {
|
||||
($fn_name:ident, $context:expr) => {
|
||||
async fn $fn_name(
|
||||
Fingerprint(fingerprint, addr): Fingerprint,
|
||||
fingerprint: Fingerprint,
|
||||
req_headers: HeaderMap,
|
||||
axum::extract::Path((username, password, stream_id)): axum::extract::Path<(
|
||||
String,
|
||||
@@ -782,7 +784,6 @@ macro_rules! create_xtream_player_api_stream {
|
||||
) -> impl IntoResponse + Send {
|
||||
xtream_player_api_stream(
|
||||
&fingerprint,
|
||||
&addr,
|
||||
&req_headers,
|
||||
&app_state,
|
||||
&api_req,
|
||||
@@ -848,7 +849,7 @@ struct XtreamApiTimeShiftRequest {
|
||||
}
|
||||
|
||||
async fn xtream_player_api_timeshift_stream(
|
||||
Fingerprint(fingerprint, addr): Fingerprint,
|
||||
fingerprint: Fingerprint,
|
||||
req_headers: HeaderMap,
|
||||
axum::extract::Query(mut api_req): axum::extract::Query<UserApiRequest>,
|
||||
axum::extract::Path(timeshift_request): axum::extract::Path<XtreamApiTimeShiftRequest>,
|
||||
@@ -891,7 +892,6 @@ async fn xtream_player_api_timeshift_stream(
|
||||
|
||||
xtream_player_api_stream(
|
||||
&fingerprint,
|
||||
&addr,
|
||||
&req_headers,
|
||||
&app_state,
|
||||
&api_req,
|
||||
@@ -908,7 +908,7 @@ async fn xtream_player_api_timeshift_stream(
|
||||
}
|
||||
|
||||
async fn xtream_player_api_timeshift_query_stream(
|
||||
Fingerprint(fingerprint, addr): Fingerprint,
|
||||
fingerprint: Fingerprint,
|
||||
req_headers: HeaderMap,
|
||||
axum::extract::Query(api_query_req): axum::extract::Query<UserApiRequest>,
|
||||
axum::extract::State(app_state): axum::extract::State<Arc<AppState>>,
|
||||
@@ -933,7 +933,6 @@ async fn xtream_player_api_timeshift_query_stream(
|
||||
}
|
||||
xtream_player_api_stream(
|
||||
&fingerprint,
|
||||
&addr,
|
||||
&req_headers,
|
||||
&app_state,
|
||||
&api_query_req,
|
||||
@@ -1585,7 +1584,7 @@ macro_rules! register_xtream_api_timeshift {
|
||||
}
|
||||
|
||||
async fn xtream_player_token_stream(
|
||||
Fingerprint(fingerprint, addr): Fingerprint,
|
||||
fingerprint: Fingerprint,
|
||||
axum::extract::Path((token, target_id, cluster, stream_id)): axum::extract::Path<(
|
||||
String,
|
||||
u16,
|
||||
@@ -1598,7 +1597,6 @@ async fn xtream_player_token_stream(
|
||||
let ctxt = try_result_bad_request!(ApiStreamContext::from_str(cluster.as_str()));
|
||||
xtream_player_api_stream_with_token(
|
||||
&fingerprint,
|
||||
&addr,
|
||||
&req_headers,
|
||||
&app_state,
|
||||
target_id,
|
||||
|
||||
@@ -14,6 +14,7 @@ use std::sync::Arc;
|
||||
use arc_swap::ArcSwapOption;
|
||||
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
|
||||
use tokio::sync::RwLock;
|
||||
use crate::auth::Fingerprint;
|
||||
use crate::utils::GeoIp;
|
||||
|
||||
const USER_GC_TTL: u64 = 900; // 15 Min
|
||||
@@ -331,11 +332,11 @@ impl ActiveUserManager {
|
||||
Self::get_active_connections(&self.user).await
|
||||
}
|
||||
|
||||
pub async fn add_connection(&self, username: &str, max_connections: u32, addr: &str, provider: &str, stream_channel: StreamChannel, user_agent: Cow<'_, str>) -> UserConnectionGuard {
|
||||
pub async fn add_connection(&self, username: &str, max_connections: u32, fingerprint: &Fingerprint, provider: &str, stream_channel: StreamChannel, user_agent: Cow<'_, str>) -> UserConnectionGuard {
|
||||
let country = {
|
||||
let geoip = self.geo_ip.load();
|
||||
if let Some(geoip_db) = (*geoip).as_ref() {
|
||||
geoip_db.lookup(&strip_port(addr))
|
||||
geoip_db.lookup(&strip_port(&fingerprint.client_ip))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -343,7 +344,8 @@ impl ActiveUserManager {
|
||||
|
||||
let stream_info = StreamInfo::new(
|
||||
username,
|
||||
addr,
|
||||
&fingerprint.addr,
|
||||
&fingerprint.client_ip,
|
||||
provider,
|
||||
stream_channel,
|
||||
user_agent.to_string(),
|
||||
@@ -364,7 +366,7 @@ impl ActiveUserManager {
|
||||
|
||||
{
|
||||
let mut user_by_addr = self.user_by_addr.write().await;
|
||||
user_by_addr.insert(addr.to_string(), username.to_string());
|
||||
user_by_addr.insert(fingerprint.addr.to_string(), username.to_string());
|
||||
}
|
||||
|
||||
if let Err(err) = self.connection_change_tx.send(ActiveUserConnectionChange::Connected(stream_info)) {
|
||||
@@ -372,7 +374,7 @@ impl ActiveUserManager {
|
||||
}
|
||||
self.log_active_user().await;
|
||||
|
||||
UserConnectionGuard::new(Arc::new(self.clone_inner()), addr, self.release_sender())
|
||||
UserConnectionGuard::new(Arc::new(self.clone_inner()), &fingerprint.addr, self.release_sender())
|
||||
}
|
||||
|
||||
fn is_log_user_enabled(&self) -> bool {
|
||||
|
||||
@@ -18,6 +18,7 @@ use std::task::{Poll};
|
||||
use axum::http::header::USER_AGENT;
|
||||
use axum::http::HeaderMap;
|
||||
use futures::task::AtomicWaker;
|
||||
use crate::auth::Fingerprint;
|
||||
|
||||
const INNER_STREAM: u8 = 0_u8;
|
||||
const GRACE_BLOCK_STREAM: u8 = 1_u8;
|
||||
@@ -40,7 +41,7 @@ impl ActiveClientStream {
|
||||
app_state: &AppState,
|
||||
user: &ProxyUserCredentials,
|
||||
connection_permission: UserConnectionPermission,
|
||||
addr: &str,
|
||||
fingerprint: &Fingerprint,
|
||||
stream_channel: StreamChannel,
|
||||
req_headers: &HeaderMap) -> Self {
|
||||
if connection_permission == UserConnectionPermission::Exhausted {
|
||||
@@ -51,11 +52,11 @@ impl ActiveClientStream {
|
||||
let provider_name = stream_details.provider_name.as_ref().map_or_else(String::new, ToString::to_string);
|
||||
|
||||
let user_agent = req_headers.get(USER_AGENT).map(|h| String::from_utf8_lossy(h.as_bytes())).unwrap_or_default();
|
||||
let user_connection_guard = Some(app_state.active_users.add_connection(username, user.max_connections, addr, &provider_name, stream_channel, user_agent).await);
|
||||
let user_connection_guard = Some(app_state.active_users.add_connection(username, user.max_connections, fingerprint, &provider_name, stream_channel, user_agent).await);
|
||||
let cfg = &app_state.app_config;
|
||||
let waker = Some(Arc::new(AtomicWaker::new()));
|
||||
let waker_clone = waker.clone();
|
||||
let grace_stop_flag = Self::stream_grace_period(app_state, &stream_details, grant_user_grace_period, user, addr, waker_clone.clone());
|
||||
let grace_stop_flag = Self::stream_grace_period(app_state, &stream_details, grant_user_grace_period, user, &fingerprint.addr, waker_clone.clone());
|
||||
let custom_response = cfg.custom_stream_response.load();
|
||||
let custom_video = custom_response.as_ref()
|
||||
.map_or((None, None), |c|
|
||||
|
||||
Reference in New Issue
Block a user