mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-11 04:51:51 +00:00
fix(engine): compare online servers' paths with their case
same_server lowercased the whole address, so files on /Team/ and /team/ (which a proxy can route to different servers) counted as one server and the online refresh sent both files' owner tokens to whichever answered. The scheme and host still compare without case; the path keeps its.
This commit is contained in:
1 parent
02c38a6d95
commit
8864068cd5
2 files changed
+11
-5
No files matched your search
@@ -590,4 +590,7 @@ fn same_server_ignores_the_default_port_before_a_path() {
|
||||
assert!(same_server("wss://share.example:443/figcraft/", "wss://share.example/figcraft/"));
|
||||
assert!(same_server("ws://host:80/x", "ws://host/x"));
|
||||
assert!(!same_server("wss://share.example:8443/figcraft/", "wss://share.example/figcraft/"));
|
||||
// The path is a route: owner tokens for /Team/ must never be sent to /team/.
|
||||
assert!(same_server("WSS://Share.Example/team/", "wss://share.example/team"));
|
||||
assert!(!same_server("wss://share.example/Team/", "wss://share.example/team/"));
|
||||
}
|
||||
@@ -117,14 +117,17 @@ pub(crate) fn plain_server(server: &str) -> String {
|
||||
/// Two addresses name the same server (case, a closing slash and the scheme's own port aside).
|
||||
pub fn same_server(a: &str, b: &str) -> bool {
|
||||
let norm = |s: &str| {
|
||||
let s = plain_server(s).to_ascii_lowercase();
|
||||
let s = plain_server(s);
|
||||
let s = s.trim_end_matches('/');
|
||||
let port = if s.starts_with("wss://") { ":443" } else { ":80" };
|
||||
let start = s.find("://").map_or(0, |i| i + 3);
|
||||
let end = s[start..].find('/').map_or(s.len(), |i| start + i);
|
||||
match s[start..end].strip_suffix(port) {
|
||||
Some(host) => format!("{}{}{}", &s[..start], host, &s[end..]),
|
||||
None => s.to_string(),
|
||||
// The scheme and host compare without case; the path routes (a proxy may send
|
||||
// `/Team/` and `/team/` to different servers), so it keeps its case.
|
||||
let head = s[..end].to_ascii_lowercase();
|
||||
let port = if head.starts_with("wss://") { ":443" } else { ":80" };
|
||||
match head[start..].strip_suffix(port) {
|
||||
Some(host) => format!("{}{}{}", &head[..start], host, &s[end..]),
|
||||
None => format!("{head}{}", &s[end..]),
|
||||
}
|
||||
};
|
||||
norm(a) == norm(b)
|
||||
|
||||
Reference in new issue
Block a user