WEB: Base Path added

This commit is contained in:
Alexey
2026-09-26 13:49:28 +03:00
parent 326c0ecdb9
commit 5feded2919
32 changed files with 1094 additions and 125 deletions
+91 -6
View File
@@ -1,5 +1,6 @@
use std::time::Duration;
use base64::Engine as _;
use tokio::sync::watch;
use tracing::{debug, error, info, warn};
@@ -80,19 +81,57 @@ pub(crate) fn print_web_proxy_links(config: &ProxyConfig) {
let Some(secret) = config.access.users.get(&profile.user) else {
continue;
};
let prefix = match profile.secret_mode {
crate::config::WebSecretMode::Plain => "",
crate::config::WebSecretMode::Dd => "dd",
let Some(vhost) = config
.web
.vhosts
.iter()
.find(|vhost| vhost.host == profile.host)
else {
continue;
};
print_maestro_line(format!(
"User: {} ({:?})",
profile.user, profile.secret_mode
));
print_maestro_line(format!(
"WEB: tg://webproxy?server={}&secret={prefix}{secret}",
profile.host,
if let Some(link) = format_web_proxy_link(
&profile.host,
&vhost.base_path,
secret,
profile.secret_mode,
) {
print_maestro_line(format!("WEB: {link}"));
}
}
}
fn format_web_proxy_link(
host: &str,
base_path: &str,
secret: &str,
mode: crate::config::WebSecretMode,
) -> Option<String> {
if base_path.is_empty() {
let prefix = match mode {
crate::config::WebSecretMode::Plain => "",
crate::config::WebSecretMode::Dd => "dd",
};
return Some(format!(
"tg://webproxy?server={host}&secret={prefix}{secret}"
));
}
let decoded = hex::decode(secret).ok()?;
let mut marked = Vec::with_capacity(decoded.len() + 2);
marked.push(0x70);
if mode == crate::config::WebSecretMode::Dd {
marked.push(0xdd);
}
marked.extend_from_slice(&decoded);
let server = url::form_urlencoded::byte_serialize(format!("{host}/{base_path}").as_bytes())
.collect::<String>();
let marked = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(marked);
Some(format!(
"tg://webproxy?server={server}&secret={marked}"
))
}
/// Durably replaces one Beobachten snapshot without following Unix symlinks.
@@ -367,3 +406,49 @@ pub(crate) async fn load_startup_proxy_config_snapshot(
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::WebSecretMode;
const SECRET: &str = "000102030405060708090a0b0c0d0e0f";
#[test]
fn root_web_proxy_links_keep_the_legacy_secret_form() {
assert_eq!(
format_web_proxy_link("proxy.example.com", "", SECRET, WebSecretMode::Plain),
Some(format!(
"tg://webproxy?server=proxy.example.com&secret={SECRET}"
))
);
assert_eq!(
format_web_proxy_link("proxy.example.com", "", SECRET, WebSecretMode::Dd),
Some(format!(
"tg://webproxy?server=proxy.example.com&secret=dd{SECRET}"
))
);
}
#[test]
fn path_web_proxy_links_use_the_tdesktop_marker() {
assert_eq!(
format_web_proxy_link(
"proxy.example.com",
"dobry-cola/super_app",
SECRET,
WebSecretMode::Plain,
),
Some("tg://webproxy?server=proxy.example.com%2Fdobry-cola%2Fsuper_app&secret=cAABAgMEBQYHCAkKCwwNDg8".to_string())
);
assert_eq!(
format_web_proxy_link(
"proxy.example.com",
"dobry-cola/super_app",
SECRET,
WebSecretMode::Dd,
),
Some("tg://webproxy?server=proxy.example.com%2Fdobry-cola%2Fsuper_app&secret=cN0AAQIDBAUGBwgJCgsMDQ4P".to_string())
);
}
}