diff --git a/Cargo.lock b/Cargo.lock index 0f762f7..664ef42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,6 +73,15 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.4.0" @@ -168,6 +177,12 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +[[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + [[package]] name = "crates-index" version = "0.15.0" @@ -254,6 +269,15 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "dirs" version = "2.0.2" @@ -416,6 +440,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getopts" version = "0.2.21" @@ -871,6 +905,12 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "openssl" version = "0.10.31" @@ -1399,6 +1439,19 @@ dependencies = [ "serde", ] +[[package]] +name = "sha-1" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4b312c3731e3fe78a185e6b9b911a7aa715b8e31cce117975219aab2acf285d" +dependencies = [ + "block-buffer", + "cfg-if 1.0.0", + "cpuid-bool", + "digest", + "opaque-debug", +] + [[package]] name = "shiny-robots" version = "0.1.0" @@ -1424,6 +1477,7 @@ dependencies = [ "semver 0.10.0", "serde", "serde_json", + "sha-1", "slog", "slog-async", "slog-term", @@ -1739,6 +1793,12 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + [[package]] name = "ucd-trie" version = "0.1.3" diff --git a/Cargo.toml b/Cargo.toml index 605b0d8..6540bb4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,3 +40,4 @@ toml = "0.5" [build-dependencies] sass-rs = "0.2" +sha-1 = "0.9" diff --git a/build.rs b/build.rs index 3fb6176..ee37440 100644 --- a/build.rs +++ b/build.rs @@ -1,10 +1,11 @@ extern crate sass_rs as sass; use std::env; -use std::fs::File; -use std::io::Write; +use std::fs; use std::path::Path; +use sha1::{Digest, Sha1}; + fn build_style() -> String { let options = sass::Options { output_style: sass::OutputStyle::Compressed, @@ -16,8 +17,13 @@ fn build_style() -> String { fn main() { let out_dir = env::var("OUT_DIR").unwrap(); - let dest_path = Path::new(&out_dir).join("style.css"); - let mut f = File::create(&dest_path).unwrap(); - f.write_all(build_style().as_bytes()).unwrap(); + let style = build_style(); + + let css_path = Path::new(&out_dir).join("style.css"); + fs::write(css_path, style.as_bytes()).unwrap(); + + let hash_path = Path::new(&out_dir).join("style.css.sha1"); + let digest = Sha1::digest(style.as_bytes()); + fs::write(hash_path, format!("{:x}", digest)).unwrap(); } diff --git a/src/server/assets.rs b/src/server/assets.rs index 84f59b3..b7e6836 100644 --- a/src/server/assets.rs +++ b/src/server/assets.rs @@ -1,2 +1,12 @@ pub static STATIC_STYLE_CSS: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/style.css")); +pub const STATIC_STYLE_CSS_PATH: &str = concat!( + "/static/style.", + include_str!(concat!(env!("OUT_DIR"), "/style.css.sha1")), + ".css" +); +pub const STATIC_STYLE_CSS_ETAG: &str = concat!( + "\"", + include_str!(concat!(env!("OUT_DIR"), "/style.css.sha1")), + "\"" +); pub static STATIC_FAVICON: &[u8] = include_bytes!("../../assets/logo.svg"); diff --git a/src/server/mod.rs b/src/server/mod.rs index e400d90..df880a9 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -2,7 +2,7 @@ use std::{env, sync::Arc, time::Instant}; use futures::future; use hyper::{ - header::{CONTENT_TYPE, LOCATION}, + header::{CACHE_CONTROL, CONTENT_TYPE, ETAG, LOCATION}, Body, Error as HyperError, Method, Request, Response, StatusCode, }; use once_cell::sync::Lazy; @@ -13,6 +13,7 @@ use slog::{error, info, o, Logger}; mod assets; mod views; +use self::assets::{STATIC_STYLE_CSS_ETAG, STATIC_STYLE_CSS_PATH}; use crate::engine::{AnalyzeDependenciesOutcome, Engine}; use crate::models::crates::{CrateName, CratePath}; use crate::models::repo::RepoPath; @@ -51,7 +52,7 @@ impl App { router.add("/", Route::Index); - router.add("/static/style.css", Route::Static(StaticFile::StyleCss)); + router.add(STATIC_STYLE_CSS_PATH, Route::Static(StaticFile::StyleCss)); router.add("/static/logo.svg", Route::Static(StaticFile::FaviconPng)); router.add( @@ -347,7 +348,9 @@ impl App { fn static_file(file: StaticFile) -> Response { match file { StaticFile::StyleCss => Response::builder() - .header(CONTENT_TYPE, "text/css") + .header(CONTENT_TYPE, "text/css; charset=utf-8") + .header(ETAG, STATIC_STYLE_CSS_ETAG) + .header(CACHE_CONTROL, "public, max-age=365000000, immutable") .body(Body::from(assets::STATIC_STYLE_CSS)) .unwrap(), StaticFile::FaviconPng => Response::builder() diff --git a/src/server/views/html/mod.rs b/src/server/views/html/mod.rs index 73de6dd..05b7996 100644 --- a/src/server/views/html/mod.rs +++ b/src/server/views/html/mod.rs @@ -8,6 +8,7 @@ pub mod error; pub mod index; pub mod status; +use crate::server::assets::STATIC_STYLE_CSS_PATH; use crate::server::SELF_BASE_URL; fn render_html(title: &str, body: B) -> Response { @@ -18,7 +19,7 @@ fn render_html(title: &str, body: B) -> Response { meta name="viewport" content="width=device-width, initial-scale=1"; title { (format!("{} - Deps.rs", title)) } link rel="icon" type="image/svg+xml" href="/static/logo.svg"; - link rel="stylesheet" type="text/css" href="/static/style.css"; + link rel="stylesheet" type="text/css" href=(STATIC_STYLE_CSS_PATH); link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Fira+Sans:400,500,600"; link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Source+Code+Pro"; link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css";