Skip to content

Fix locally hosting docs.rs for development #216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Vagrant.configure("2") do |config|
############################################################
lxc-attach -n cratesfyi-container -- apt-get update
lxc-attach -n cratesfyi-container -- apt-get install -y --no-install-recommends curl ca-certificates binutils gcc libc6-dev libmagic1
lxc-attach -n cratesfyi-container -- su - cratesfyi -c 'curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly-2018-03-25'
lxc-attach -n cratesfyi-container -- su - cratesfyi -c 'curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly-2018-06-03'
############################################################
# Creating rustc links for cratesfyi user #
Expand Down
8 changes: 5 additions & 3 deletions src/docbuilder/chroot_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::path::PathBuf;
use std::fs::remove_dir_all;
use postgres::Connection;
use rustc_serialize::json::Json;
use error::Result;
use error::{Result, ResultExt};


/// List of targets supported by docs.rs
Expand Down Expand Up @@ -398,13 +398,15 @@ impl DocBuilder {
let file_name = format!("{}-{}.{}", spl[0], rustc_version, spl[1]);
let source_path = source.join(&file_name);
let destination_path = destination.join(&file_name);
try!(copy(source_path, destination_path));
try!(copy(&source_path, &destination_path)
.chain_err(|| format!("couldn't copy '{}' to '{}'", source_path.display(), destination_path.display())));
}

for file in files.1.iter() {
let source_path = source.join(file);
let destination_path = destination.join(file);
try!(copy(source_path, destination_path));
try!(copy(&source_path, &destination_path)
.chain_err(|| format!("couldn't copy '{}' to '{}'", source_path.display(), destination_path.display())));
}

let conn = try!(connect_db());
Expand Down
10 changes: 8 additions & 2 deletions src/web/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const OPENSEARCH_XML: &'static [u8] = include_bytes!("opensearch.xml");


struct CratesfyiHandler {
shared_resource_handler: Box<Handler>,
router_handler: Box<Handler>,
database_file_handler: Box<Handler>,
static_handler: Box<Handler>,
Expand Down Expand Up @@ -186,12 +187,14 @@ impl CratesfyiHandler {
rustdoc::rustdoc_html_server_handler,
"crate_version_target_html");

let shared_resources = Self::chain(rustdoc::SharedResourceHandler);
let router_chain = Self::chain(router);
let prefix = PathBuf::from(env::var("CRATESFYI_PREFIX").unwrap()).join("public_html");
let static_handler = Static::new(prefix)
.cache(Duration::from_secs(STATIC_FILE_CACHE_DURATION));

CratesfyiHandler {
shared_resource_handler: Box::new(shared_resources),
router_handler: Box::new(router_chain),
database_file_handler: Box::new(file::DatabaseFileHandler),
static_handler: Box::new(static_handler),
Expand All @@ -202,10 +205,13 @@ impl CratesfyiHandler {

impl Handler for CratesfyiHandler {
fn handle(&self, req: &mut Request) -> IronResult<Response> {
// try router first then db/static file handler
// try serving shared rustdoc resources first, then router, then db/static file handler
// return 404 if none of them return Ok
self.router_handler
self.shared_resource_handler
.handle(req)
.or_else(|e| {
self.router_handler.handle(req).or(Err(e))
})
.or_else(|e| {
// if router fails try to serve files from database first
self.database_file_handler.handle(req).or(Err(e))
Expand Down
31 changes: 30 additions & 1 deletion src/web/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rustc_serialize::json::{Json, ToJson};
use std::collections::BTreeMap;
use iron::headers::{Expires, HttpDate, CacheControl, CacheDirective};
use time;

use iron::Handler;


#[derive(Debug)]
Expand Down Expand Up @@ -110,6 +110,10 @@ pub fn rustdoc_redirector_handler(req: &mut Request) -> IronResult<Response> {
}


/// Serves documentation generated by rustdoc.
///
/// This includes all HTML files for an individual crate, as well as the `search-index.js`, which is
/// also crate-specific.
pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {

let router = extension!(req, Router);
Expand Down Expand Up @@ -251,3 +255,28 @@ pub fn badge_handler(req: &mut Request) -> IronResult<Response> {
CacheDirective::MustRevalidate]));
Ok(resp)
}

/// Serves shared web resources used by rustdoc-generated documentation.
///
/// This includes common `css` and `js` files that only change when the compiler is updated, but are
/// otherwise the same for all crates documented with that compiler. Those have a custom handler to
/// deduplicate them and save space.
pub struct SharedResourceHandler;

impl Handler for SharedResourceHandler {
fn handle(&self, req: &mut Request) -> IronResult<Response> {
let path = req.url.path();
let filename = path.last().unwrap(); // unwrap is fine: vector is non-empty
let suffix = filename.split('.').last().unwrap(); // unwrap is fine: split always works
if ["js", "css", "woff", "svg"].contains(&suffix) {
let conn = extension!(req, Pool);

if let Some(file) = File::from_path(conn, filename) {
return Ok(file.serve());
}
}

// Just always return a 404 here - the main handler will then try the other handlers
Err(IronError::new(Nope::ResourceNotFound, status::NotFound))
}
}