From f3848a34c391841a2516a9e6ad1f80f6f490c6d0 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 15 Apr 2019 15:33:19 -0500 Subject: [PATCH] redirect all *.ico paths to /favicon.ico several rustdoc versions try to use rustdoc's built-in favicon, which overrides docs.rs's own favicon. instead of modifying these pages to remove the reference to their favicon, instead redirect them to the main favicon --- src/web/mod.rs | 23 +++++++++++++++++++++-- src/web/rustdoc.rs | 4 ++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/web/mod.rs b/src/web/mod.rs index 63761b7f6..ba6932c22 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -9,7 +9,7 @@ macro_rules! ctry { ($result:expr) => (match $result { Ok(v) => v, Err(e) => { - return super::page::Page::new(format!("{:?}", e)).title("An error has occured") + return $crate::web::page::Page::new(format!("{:?}", e)).title("An error has occured") .set_status(::iron::status::BadRequest).to_resp("resp"); } }) @@ -21,7 +21,7 @@ macro_rules! cexpect { ($option:expr) => (match $option { Some(v) => v, None => { - return super::page::Page::new("Resource not found".to_owned()) + return $crate::web::page::Page::new("Resource not found".to_owned()) .title("An error has occured") .set_status(::iron::status::BadRequest).to_resp("resp"); } @@ -485,6 +485,25 @@ fn opensearch_xml_handler(_: &mut Request) -> IronResult { Ok(response) } +fn ico_handler(req: &mut Request) -> IronResult { + use iron::Url; + + if let Some(&"favicon.ico") = req.url.path().last() { + // if we're looking for exactly "favicon.ico", we need to defer to the handler that loads + // from `public_html`, so return a 404 here to make the main handler carry on + Err(IronError::new(error::Nope::ResourceNotFound, status::NotFound)) + } else { + // if we're looking for something like "favicon-20190317-1.35.0-nightly-c82834e2b.ico", + // redirect to the plain one so that the above branch can trigger with the correct filename + let url = ctry!(Url::parse(&format!("{}://{}:{}/favicon.ico", + req.url.scheme(), + req.url.host(), + req.url.port())[..])); + + Ok(redirect(url)) + } +} + /// MetaData used in header #[derive(Debug)] pub struct MetaData { diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index f326ddf5a..ff8e44815 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -112,6 +112,10 @@ pub fn rustdoc_redirector_handler(req: &mut Request) -> IronResult { // javascript files should be handled by the file server instead of erroneously // redirecting to the crate root page return rustdoc_html_server_handler(req); + } else if req.url.as_ref().path_segments().unwrap().last().map_or(false, |s| s.ends_with(".ico")) { + // route .ico files into their dedicated handler so that docs.rs's favicon is always + // displayed + return super::ico_handler(req); } let router = extension!(req, Router);