web_ui_path fixes

This commit is contained in:
euzu
2025-08-05 14:20:13 +02:00
parent bb79c201c4
commit 420912a79d
11 changed files with 45 additions and 29 deletions
+2 -2
View File
@@ -16,7 +16,7 @@ use log::error;
use serde_json::json;
use shared::error::TuliproxError;
use shared::model::{ApiProxyConfigDto, ApiProxyServerInfoDto, ConfigDto, InputType, IpCheckDto, PlaylistRequest, PlaylistRequestType, StatusCheck, TargetUserDto, XtreamPlaylistItem};
use shared::utils::{concat_path, sanitize_sensitive_info};
use shared::utils::{concat_path_leading_slash, sanitize_sensitive_info};
use std::collections::{BTreeMap, HashSet};
use std::sync::Arc;
use crate::utils::prepare_sources_batch;
@@ -349,5 +349,5 @@ pub fn v1_api_register(web_auth_enabled: bool, app_state: Arc<AppState>, web_ui_
if config.web_ui.as_ref().is_none_or(|c| c.user_ui_enabled) {
base_router = base_router.merge(user_api_register(app_state));
}
base_router.nest(&concat_path(web_ui_path, "api/v1"), router)
base_router.nest(&concat_path_leading_slash(web_ui_path, "api/v1"), router)
}
+8 -8
View File
@@ -6,7 +6,7 @@ use axum::response::IntoResponse;
use log::error;
use serde_json::json;
use shared::model::{TokenResponse, UserCredential};
use shared::utils::{concat_path, CONSTANTS};
use shared::utils::{concat_path_leading_slash, CONSTANTS};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use tower::Service;
@@ -107,10 +107,10 @@ async fn index(
match tokio::fs::read_to_string(&path).await {
Ok(content) => {
let mut new_content = CONSTANTS.re_base_href.replace_all(&content, |caps: &regex::Captures| {
format!(r#"{}="/{}""#, &caps[1], concat_path(&web_ui_path, &caps[2]).trim_start_matches('/'))
format!(r#"{}="{}""#, &caps[1], concat_path_leading_slash(web_ui_path, &caps[2]))
}).to_string();
let base_href = format!(r#"<head><base href="/{}/">"#, web_ui_path.trim_matches('/'));
let base_href = format!(r#"<head><base href="/{web_ui_path}/">"#);
if let Some(pos) = new_content.find("<head>") {
new_content.replace_range(pos..pos + 6, &base_href);
}
@@ -139,13 +139,13 @@ async fn index_config(
if let Some(api) = json_data.get_mut("api") {
if let Some(api_url) = api.get_mut("apiUrl") {
if let Some(url) = api_url.as_str() {
let new_url = concat_path(web_ui_path, url);
let new_url = concat_path_leading_slash(web_ui_path, url);
*api_url = json!(new_url);
}
}
if let Some(auth_url) = api.get_mut("authUrl") {
if let Some(url) = auth_url.as_str() {
let new_url = concat_path(web_ui_path, url);
let new_url = concat_path_leading_slash(web_ui_path, url);
*auth_url = json!(new_url);
}
}
@@ -177,12 +177,12 @@ pub fn index_register_without_path(web_dir_path: &Path) -> axum::Router<Arc<AppS
pub fn index_register_with_path(web_dir_path: &Path, web_ui_path: &str) -> axum::Router<Arc<AppState>> {
axum::Router::new()
.nest(&concat_path(web_ui_path, "auth"), axum::Router::new()
.nest(&concat_path_leading_slash(web_ui_path, "auth"), axum::Router::new()
.route("/token", axum::routing::post(token))
.route("/refresh", axum::routing::post(token_refresh)))
.merge(axum::Router::new()
.route(&format!("/{}/", web_ui_path.trim_matches('/')), axum::routing::get(index))
.route(&concat_path(web_ui_path, "config.json"), axum::routing::get(index_config))
.route(&format!("/{web_ui_path}/"), axum::routing::get(index))
.route(&concat_path_leading_slash(web_ui_path, "config.json"), axum::routing::get(index_config))
.fallback({
let mut serve_dir = tower_http::services::ServeDir::new(web_dir_path);
let path_prefix = web_ui_path.to_string();
+3 -3
View File
@@ -10,7 +10,7 @@ use axum::{
use log::{error, info};
use shared::model::{ProtocolHandler, ProtocolHandlerMemory, ProtocolMessage, UserRole, WsCloseCode, PROTOCOL_VERSION};
use std::sync::Arc;
use shared::utils::concat_path;
use shared::utils::{concat_path_leading_slash};
// WebSocket upgrade handler
async fn websocket_handler(
@@ -33,12 +33,12 @@ async fn websocket_handler_auth(
pub fn ws_api_register(web_auth_enabled: bool, web_ui_path: &str) -> axum::Router<Arc<AppState>> {
if web_auth_enabled {
axum::Router::new().route(
&format!("/{}", concat_path(web_ui_path.trim_start_matches('/'), "ws")),
&concat_path_leading_slash(web_ui_path, "ws"),
axum::routing::get(websocket_handler_auth),
)
} else {
axum::Router::new().route(
&format!("/{}", concat_path(web_ui_path.trim_start_matches('/'), "ws")),
&concat_path_leading_slash(web_ui_path, "ws"),
axum::routing::get(websocket_handler),
)
}
+3 -3
View File
@@ -30,7 +30,7 @@ use std::path::PathBuf;
use std::sync::Arc;
use tokio_util::sync::CancellationToken;
use tower_governor::key_extractor::SmartIpKeyExtractor;
use shared::utils::concat_path;
use shared::utils::{concat_path_leading_slash};
fn get_web_dir_path(web_ui_enabled: bool, web_root: &str) -> Result<PathBuf, std::io::Error> {
let web_dir = web_root.to_string();
@@ -276,11 +276,11 @@ pub async fn start_server(
if web_ui_enabled {
router = router
.nest_service(
&concat_path(&web_ui_path, "static"),
&concat_path_leading_slash(&web_ui_path, "static"),
tower_http::services::ServeDir::new(web_dir_path.join("static")),
)
.nest_service(
&concat_path(&web_ui_path, "assets"),
&concat_path_leading_slash(&web_ui_path, "assets"),
tower_http::services::ServeDir::new(web_dir_path.join("assets")),
)
.merge(v1_api_register(
+3 -3
View File
@@ -1,4 +1,4 @@
use log::{error, info};
use log::{error, info, trace};
use tokio::task;
use shared::model::{ConfigType, PlaylistUpdateState};
use crate::api::model::{ActiveUserConnectionChangeReceiver};
@@ -31,13 +31,13 @@ impl EventManager {
tokio::select! {
Some((user_count, connection_count)) = active_user_change_rx.recv() => {
if let Err(e) = channel_tx_clone.send(EventMessage::ActiveUser(user_count, connection_count)) {
error!("Failed to send active user change event: {e}");
trace!("Failed to send active user change event: {e}");
}
}
Some((provider, connection_count)) = provider_change_rx.recv() => {
if let Err(e) = channel_tx_clone.send(EventMessage::ActiveProvider(provider, connection_count)) {
error!("Failed to send active provider change event: {e}");
trace!("Failed to send active provider change event: {e}");
}
}
else => {
+14 -1
View File
@@ -124,6 +124,19 @@ pub fn get_base_url_from_str(url: &str) -> Option<String> {
pub fn concat_path(first: &str, second: &str) -> String {
let first = first.trim_end_matches('/');
let second = second.trim_start_matches('/');
match (first.is_empty(), second.is_empty()) {
(true, true) => String::new(),
(true, false) => second.to_string(),
(false, true) => first.to_string(),
(false, false) => format!("{first}/{second}"),
}
}
format!("{first}/{second}")
pub fn concat_path_leading_slash(first: &str, second: &str) -> String {
let path = concat_path(first, second);
if path.is_empty() {
return path;
}
let path = path.trim_start_matches('/');
format!("/{path}")
}
+2 -2
View File
@@ -6,7 +6,7 @@ use futures_signals::signal::Mutable;
use futures_signals::signal::SignalExt;
use shared::model::{TokenResponse, UserCredential};
use std::future::Future;
use shared::utils::concat_path;
use shared::utils::{concat_path, concat_path_leading_slash};
#[derive(Debug)]
pub struct AuthService {
@@ -19,7 +19,7 @@ impl AuthService {
pub fn new() -> Self {
let base_href = get_base_href();
Self {
auth_path: format!("{base_href}auth"),
auth_path: concat_path_leading_slash(&base_href, "auth"),
username: RefCell::new(String::new()),
auth_channel: Mutable::new(false),
}
+3 -2
View File
@@ -9,6 +9,7 @@ use log::error;
use futures_signals::signal::Mutable;
use futures_signals::signal::SignalExt;
use shared::foundation::filter::{get_filter, prepare_templates};
use shared::utils::concat_path_leading_slash;
pub struct ConfigService {
pub ui_config: Rc<WebConfig>,
@@ -27,8 +28,8 @@ impl ConfigService {
server_config: RefCell::new(None),
config_channel: Mutable::new(None),
is_fetching: AtomicBool::new(false),
config_path: format!("{base_href}api/v1/config"),
ip_check_path: format!("{base_href}api/v1/ipinfo"),
config_path: concat_path_leading_slash(&base_href, "api/v1/config"),
ip_check_path: concat_path_leading_slash(&base_href, "api/v1/ipinfo"),
}
}
+3 -2
View File
@@ -2,6 +2,7 @@ use crate::services::{get_base_href, request_post};
use log::error;
use shared::model::{PlaylistCategoriesResponse, PlaylistRequest, UiPlaylistCategories};
use std::rc::Rc;
use shared::utils::concat_path_leading_slash;
pub struct PlaylistService {
target_update_api_path: String,
@@ -17,8 +18,8 @@ impl PlaylistService {
pub fn new() -> Self {
let base_href = get_base_href();
Self {
target_update_api_path: format!("{base_href}api/v1/playlist/update"),
playlist_api_path: format!("{base_href}api/v1/playlist"),
target_update_api_path: concat_path_leading_slash(&base_href, "api/v1/playlist/update"),
playlist_api_path: concat_path_leading_slash(&base_href, "api/v1/playlist"),
}
}
pub async fn update_targets(&self, targets: &[&str]) -> bool {
+2 -1
View File
@@ -1,6 +1,7 @@
use std::rc::Rc;
use crate::services::{get_base_href, request_get};
use shared::model::StatusCheck;
use shared::utils::concat_path_leading_slash;
pub struct StatusService {
status_path: String,
@@ -16,7 +17,7 @@ impl StatusService {
pub fn new() -> Self {
let base_href = get_base_href();
Self {
status_path: format!("{base_href}api/v1/status"),
status_path: concat_path_leading_slash(&base_href, "api/v1/status"),
}
}
+2 -2
View File
@@ -7,7 +7,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use web_sys::js_sys::{Uint8Array, ArrayBuffer};
use log::{debug, error, trace};
use shared::model::{ProtocolMessage, PROTOCOL_VERSION};
use shared::utils::concat_path;
use shared::utils::{concat_path_leading_slash};
use crate::model::EventMessage;
use crate::services::{get_base_href, get_token, EventService, StatusService};
@@ -27,7 +27,7 @@ impl WebSocketService {
ws: Rc::new(RefCell::new(None)),
status_service,
event_service,
ws_path: concat_path(&base_href, "ws"),
ws_path: concat_path_leading_slash(&base_href, "ws"),
}
}