Files
glchat/desktop/src-tauri/src/instance.rs
T

64 lines
2.8 KiB
Rust
Raw Normal View History

//! Адрес инстанса и границы навигации.
//!
//! Desktop-обёртка загружает тот же клиент, что и браузер, но только с одного
//! адреса: переходы на сторонние сайты уходят в системный браузер
//! (docs/client-tauri.md §6).
use url::Url;
/// Приводит введённый пользователем адрес к абсолютному URL.
///
/// Допускаются `http` и `https`; схема по умолчанию — `https`, чтобы в поле
/// настроек можно было написать просто `gl.mhspx.su`.
pub fn normalize(input: &str) -> Result<Url, String> {
let trimmed = input.trim();
if trimmed.is_empty() {
return Err("адрес инстанса не заполнен".to_string());
}
let candidate = if trimmed.contains("://") {
trimmed.to_string()
} else {
format!("https://{trimmed}")
};
let url = Url::parse(&candidate).map_err(|error| format!("некорректный адрес: {error}"))?;
match url.scheme() {
"http" | "https" => {}
other => {
return Err(format!(
"поддерживаются только http и https, а не «{other}»"
))
}
}
if url.host_str().unwrap_or_default().is_empty() {
return Err("в адресе нет имени хоста".to_string());
}
Ok(url)
}
/// Строка адреса для загрузки в окно: без завершающего слэша.
pub fn display(url: &Url) -> String {
url.as_str().trim_end_matches('/').to_string()
}
/// Хост адреса — граница, внутри которой разрешена навигация webview.
pub fn host(url: &Url) -> String {
url.host_str().unwrap_or_default().to_ascii_lowercase()
}
/// Разрешена ли навигация внутри окна.
///
/// Свой инстанс и локальные страницы обёртки (`tauri://localhost`) — да,
/// всё остальное открывается в системном браузере.
pub fn navigation_allowed(target: &Url, instance_host: &str) -> bool {
match target.scheme() {
// Локальные ресурсы обёртки: страница настроек.
"tauri" | "asset" => true,
"http" | "https" => {
let host = target.host_str().unwrap_or_default().to_ascii_lowercase();
// На Windows/Linux локальная страница отдаётся как http://tauri.localhost.
host == "tauri.localhost" || (!instance_host.is_empty() && host == instance_host)
}
_ => false,
}
}