feat: GuiPresence (chat-service presence backend, gateway route, mod module); restore TODO history
This commit is contained in:
parent
8d9a2ad0d6
commit
e82efb74e7
44 changed files with 2202 additions and 19 deletions
|
|
@ -8,6 +8,7 @@ pub struct Config {
|
|||
pub accounts_http_url: String,
|
||||
pub accounts_grpc_url: String,
|
||||
pub configs_http_url: String,
|
||||
pub chat_http_url: String,
|
||||
pub site_origin: String,
|
||||
/// Directory served read-only under `GET /downloads/*` — today just
|
||||
/// `lovisual.jar`, the mod's direct download (see TODO.md «Скачивание»).
|
||||
|
|
@ -33,6 +34,7 @@ impl Config {
|
|||
accounts_http_url: var("ACCOUNTS_HTTP_URL")?,
|
||||
accounts_grpc_url: var("ACCOUNTS_GRPC_URL")?,
|
||||
configs_http_url: var("CONFIGS_HTTP_URL")?,
|
||||
chat_http_url: var("CHAT_HTTP_URL")?,
|
||||
site_origin: var("SITE_ORIGIN")?,
|
||||
downloads_dir: std::env::var("DOWNLOADS_DIR").unwrap_or_else(|_| "downloads".into()),
|
||||
trust_proxy: std::env::var("TRUST_PROXY").is_ok_and(|v| v == "true"),
|
||||
|
|
@ -71,6 +73,7 @@ mod tests {
|
|||
accounts_http_url: String::new(),
|
||||
accounts_grpc_url: String::new(),
|
||||
configs_http_url: String::new(),
|
||||
chat_http_url: String::new(),
|
||||
site_origin: "http://localhost:5173".into(),
|
||||
downloads_dir: "downloads".into(),
|
||||
trust_proxy: false,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ pub struct Upstreams {
|
|||
pub client: reqwest::Client,
|
||||
pub accounts: String,
|
||||
pub configs: String,
|
||||
pub chat: String,
|
||||
pub internal_key: HeaderValue,
|
||||
}
|
||||
|
||||
|
|
@ -44,6 +45,7 @@ impl Upstreams {
|
|||
.build()?,
|
||||
accounts: cfg.accounts_http_url.trim_end_matches('/').to_owned(),
|
||||
configs: cfg.configs_http_url.trim_end_matches('/').to_owned(),
|
||||
chat: cfg.chat_http_url.trim_end_matches('/').to_owned(),
|
||||
internal_key: HeaderValue::from_str(&cfg.internal_key)?,
|
||||
})
|
||||
}
|
||||
|
|
@ -67,6 +69,7 @@ pub async fn proxy(State(up): State<Arc<Upstreams>>, req: Request) -> Response {
|
|||
let base = match target {
|
||||
Upstream::Accounts => &up.accounts,
|
||||
Upstream::Configs => &up.configs,
|
||||
Upstream::Chat => &up.chat,
|
||||
};
|
||||
let path_and_query = req.uri().path_and_query().map_or("/", |p| p.as_str());
|
||||
let url = format!("{base}{path_and_query}");
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
pub enum Upstream {
|
||||
Accounts,
|
||||
Configs,
|
||||
Chat,
|
||||
}
|
||||
|
||||
pub fn upstream_for(path: &str) -> Option<Upstream> {
|
||||
match path.trim_start_matches('/').split('/').next()? {
|
||||
"auth" | "device" | "avatars" | "media" | "me" | "users" => Some(Upstream::Accounts),
|
||||
"configs" | "showcase" => Some(Upstream::Configs),
|
||||
"presence" => Some(Upstream::Chat),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +28,7 @@ mod tests {
|
|||
);
|
||||
assert_eq!(upstream_for("/configs/shared/ABC"), Some(Upstream::Configs));
|
||||
assert_eq!(upstream_for("/showcase"), Some(Upstream::Configs));
|
||||
assert_eq!(upstream_for("/presence/gui"), Some(Upstream::Chat));
|
||||
assert_eq!(upstream_for("/authx"), None);
|
||||
assert_eq!(upstream_for("/"), None);
|
||||
assert_eq!(upstream_for("/health"), None);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ pub fn rules() -> Vec<Rule> {
|
|||
),
|
||||
rule(Method::POST, "/avatars", Quota::per_hour(n(5)), Account),
|
||||
rule(Method::GET, "/showcase*", Quota::per_minute(n(60)), Ip),
|
||||
// The mod syncs menu presence about 3 times a second while a menu is open.
|
||||
rule(Method::POST, "/presence/*", Quota::per_second(n(6)), Account),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue