From f86a1f1afb46a6634d46f676d7ccbdca6772d66a Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 29 Mar 2019 15:16:36 -0500 Subject: [PATCH] redirect from docs.rs/crate-name to crate details if docs failed --- src/web/rustdoc.rs | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index 033e0c80d..d9a3f2d87 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -87,6 +87,23 @@ pub fn rustdoc_redirector_handler(req: &mut Request) -> IronResult { Ok(resp) } + fn redirect_to_crate(req: &Request, + name: &str, + vers: &str) + -> IronResult { + let url = ctry!(Url::parse(&format!("{}://{}:{}/crate/{}/{}", + req.url.scheme(), + req.url.host(), + req.url.port(), + name, + vers)[..])); + + let mut resp = Response::with((status::Found, Redirect(url))); + resp.headers.set(Expires(HttpDate(time::now()))); + + Ok(resp) + } + let router = extension!(req, Router); // this handler should never called without crate pattern let crate_name = cexpect!(router.find("crate")); @@ -99,18 +116,23 @@ pub fn rustdoc_redirector_handler(req: &mut Request) -> IronResult { None => return Err(IronError::new(Nope::CrateNotFound, status::NotFound)), }; - // get target name + // get target name and whether it has docs // FIXME: This is a bit inefficient but allowing us to use less code in general - let target_name: String = - ctry!(conn.query("SELECT target_name - FROM releases - INNER JOIN crates ON crates.id = releases.crate_id - WHERE crates.name = $1 AND releases.version = $2", - &[&crate_name, &version])) - .get(0) - .get(0); - - redirect_to_doc(req, &crate_name, &version, &target_name) + let (target_name, has_docs): (String, bool) = { + let rows = ctry!(conn.query("SELECT target_name, rustdoc_status + FROM releases + INNER JOIN crates ON crates.id = releases.crate_id + WHERE crates.name = $1 AND releases.version = $2", + &[&crate_name, &version])); + + (rows.get(0).get(0), rows.get(0).get(1)) + }; + + if has_docs { + redirect_to_doc(req, &crate_name, &version, &target_name) + } else { + redirect_to_crate(req, &crate_name, &version) + } }