From 80918c2ef9efafa30120a6c156cf14843f589946 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 8 Dec 2023 17:29:30 +0100 Subject: [PATCH] fix deplinks. --- src/bin/server.rs | 53 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/src/bin/server.rs b/src/bin/server.rs index f86b318..4db04bc 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -149,12 +149,7 @@ impl Thing { Ok(resp) } - async fn guess_redirect( - &self, - req: &Request, - mut krate: Option<&str>, - mut version: Option<&str>, - ) -> anyhow::Result> { + fn cookies(&self, req: &Request) -> HashMap { // Parse cookies let mut cookies = HashMap::new(); if let Some(h) = req.headers().get("Cookie") { @@ -164,6 +159,16 @@ impl Thing { } } } + cookies + } + + async fn guess_redirect( + &self, + req: &Request, + mut krate: Option<&str>, + mut version: Option<&str>, + ) -> anyhow::Result> { + let cookies = self.cookies(req); // Crate let krates = self.list_crates()?; @@ -246,7 +251,33 @@ impl Thing { let mut zup_path = vec!["flavors"]; zup_path.extend_from_slice(&path[2..]); let mut data = match zup.read(&zup_path) { - Err(e) if e.kind() == ErrorKind::NotFound => return self.resp_404(), + Err(e) if e.kind() == ErrorKind::NotFound => { + // check if it's due to incorrect flavor. + if zup.open(&["flavors", path[3]]).is_ok() { + // if flavor exists, path is wrong, so do 404. + return self.resp_404(); + } else { + // flavor doesn't exist, redirect to the default flavor. + let cookies = self.cookies(&req); + + let flavors = self.list_flavors(krate, version)?; + let flavor = cookies + .get(&format!("crate-{}-flavor", krate)) + .map(|s| s.as_str()); + let mut flavor = flavor.unwrap_or(&flavors[0]); + if flavors.iter().find(|s| *s == flavor).is_none() { + flavor = &flavors[0]; + } + + return self.resp_redirect(&format!( + "/{}/{}/{}/{}", + krate, + version, + flavor, + path[3..].join("/") + )); + } + } x => x?, } .into_owned(); @@ -285,6 +316,14 @@ impl Thing { .into(); } + if link.starts_with(b"/__DOCSERVER_DEPLINK/") { + let link_path = std::str::from_utf8(&link[21..]).unwrap(); + let (krate, link_path) = link_path.split_once('/').unwrap(); + let (_, link_path) = link_path.split_once('/').unwrap(); + + link = format!("/{krate}/git/{flavor}/{link_path}").into(); + } + let mut res = Vec::new(); res.extend_from_slice(attr); res.extend_from_slice(b"=");