| 11 | } |
| 12 | |
| 13 | fn finalize_url(path: &str, query: BTreeMap<String, String>) -> String { |
| 14 | #[cfg(feature = "qhash")] |
| 15 | { |
| 16 | use std::collections::BTreeSet; |
| 17 | |
| 18 | let qhash = { |
| 19 | let secret = env::var("HASH_SECRET"); |
| 20 | if let Ok(secret) = secret { |
| 21 | let set = query |
| 22 | .iter() |
| 23 | .filter(|(key, _)| !matches!(key.as_str(), "qhash" | "range" | "rewrite")) |
| 24 | .map(|(key, value)| (key.as_bytes().to_owned(), value.as_bytes().to_owned())) |
| 25 | .collect::<BTreeSet<_>>(); |
| 26 | |
| 27 | let mut hasher = blake3::Hasher::new(); |
| 28 | |
| 29 | for (key, value) in set { |
| 30 | hasher.update(&key); |
| 31 | hasher.update(&value); |
| 32 | } |
| 33 | |
| 34 | hasher.update(path.as_bytes()); |
| 35 | |
| 36 | hasher.update(secret.as_bytes()); |
| 37 | |
| 38 | let hash = hasher.finalize().to_hex(); |
| 39 | |
| 40 | Some(hash[..8].to_owned()) |
| 41 | } else { |
| 42 | None |
| 43 | } |
| 44 | }; |
| 45 | |
| 46 | if let Some(qhash) = qhash { |
| 47 | let mut query = QString::new(query.into_iter().collect::<Vec<_>>()); |
| 48 | query.add_pair(("qhash", qhash)); |
| 49 | return format!("{}?{}", path, query); |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | let query = QString::new(query.into_iter().collect::<Vec<_>>()); |
| 54 | format!("{}?{}", path, query) |
| 55 | } |
| 56 | |
| 57 | pub fn localize_url(url: &str, host: &str) -> String { |
| 58 | if url.starts_with("https://") { |