diff --git a/src/web/mod.rs b/src/web/mod.rs index cf35f8336..985705bfb 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -111,7 +111,7 @@ impl CratesfyiHandler { let shared_resources = Self::chain(&pool_factory, rustdoc::SharedResourceHandler); let router_chain = Self::chain(&pool_factory, routes.iron_router()); - let prefix = PathBuf::from(env::var("CRATESFYI_PREFIX").unwrap()).join("public_html"); + let prefix = PathBuf::from(env::var("CRATESFYI_PREFIX").expect("CRATESFYI_PREFIX environment variable does not exists")).join("public_html"); let static_handler = Static::new(prefix) .cache(Duration::from_secs(STATIC_FILE_CACHE_DURATION)); diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index 07492fd62..deebfaf24 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -20,6 +20,7 @@ use time; use iron::Handler; use utils; +const DIR_DEFAULT_FILE: &str = "index.html"; #[derive(Debug)] struct RustdocPage { @@ -238,26 +239,28 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { return Ok(super::redirect(canonical)); } - let path = { - let mut path = req_path.join("/"); - if path.ends_with('/') { - req_path.pop(); // get rid of empty string - path.push_str("index.html"); - req_path.push("index.html"); - } - path + let mut path = req_path.join("/"); + + //If it is a directory, we default to looking + if path.ends_with("/") { + path.push_str(DIR_DEFAULT_FILE); + req_path.push(DIR_DEFAULT_FILE); + } + + if !path.ends_with(".html") { + if let Some(file) = File::from_path(&conn, &path) { + return Ok(file.serve()); + }; + path.push_str("/"); + path.push_str(DIR_DEFAULT_FILE); + req_path.push(DIR_DEFAULT_FILE); }; let file = match File::from_path(&conn, &path) { - Some(f) => f, + Some(file) => file, None => return Err(IronError::new(Nope::ResourceNotFound, status::NotFound)), }; - // serve file directly if it's not html - if !path.ends_with(".html") { - return Ok(file.serve()); - } - let mut content = RustdocPage::default(); let file_content = ctry!(String::from_utf8(file.0.content)); @@ -315,7 +318,7 @@ fn path_for_version(req_path: &[&str], target_name: &str, conn: &Connection) -> return req_path[3..].join("/"); } // this page doesn't exist in the latest version - let search_item = if *req_path.last().unwrap() == "index.html" { + let search_item = if *req_path.last().unwrap() == DIR_DEFAULT_FILE { // this is a module req_path[req_path.len() - 2] } else { @@ -438,8 +441,11 @@ mod test { db.fake_release() .name("buggy").version("0.1.0") .build_result_successful(true) - .rustdoc_file("settings.html", b"some data") + .rustdoc_file("settings.html", b"some setting data") .rustdoc_file("all.html", b"some data 2") + .rustdoc_file("file_without_ext", b"some data 3") + .rustdoc_file("some_module/directory/index.html", b"some data 3") + .rustdoc_file("some_module/file_without_ext", b"some data 3") .create()?; db.fake_release() .name("buggy").version("0.2.0") @@ -447,9 +453,12 @@ mod test { .create()?; let web = env.frontend(); assert_success("/", web)?; + assert_success("/crate/buggy/0.1.0", web)?; assert_success("/crate/buggy/0.1.0/", web)?; assert_success("/buggy/0.1.0/settings.html", web)?; assert_success("/buggy/0.1.0/all.html", web)?; + assert_success("/buggy/0.1.0/some_module/file_without_ext", web)?; + assert_success("/buggy/0.1.0/some_module/directory", web)?; Ok(()) }); } @@ -484,6 +493,7 @@ mod test { .rustdoc_file("dummy/index.html", b"some content") .rustdoc_file("all.html", b"html") .default_target(target).create()?; + let base = "/dummy/0.3.0/dummy/"; assert_success(base, web)?; assert_redirect("/dummy/0.3.0/x86_64-unknown-linux-gnu/dummy/", base, web)?;