feat: cache control headers for assets
Diff
Cargo.lock | 28 ++++++++++++++--------------
src/bin/server.rs | 5 +++++
src/core/cache.rs | 41 +++++++++++++++++++++++++++++++++++++++++
src/core/mod.rs | 1 +
4 files changed, 61 insertions(+), 14 deletions(-)
@@ -41,9 +41,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86"
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
[[package]]
name = "async-compression"
@@ -56,7 +56,7 @@ dependencies = [
"flate2",
"futures-core",
"memchr",
"pin-project-lite 0.2.3",
"pin-project-lite 0.2.4",
]
[[package]]
@@ -169,9 +169,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "bytes"
version = "1.0.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1f8e949d755f9d79112b5bb46938e0ef9d3804a0b16dfab13aafcaa5f0fa72"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]]
name = "cc"
@@ -374,7 +374,7 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-task",
"pin-project-lite 0.2.3",
"pin-project-lite 0.2.4",
"pin-utils",
"slab",
]
@@ -484,7 +484,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747"
dependencies = [
"bytes 1.0.0",
"bytes 1.0.1",
"fnv",
"itoa",
]
@@ -625,9 +625,9 @@ checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
[[package]]
name = "log"
version = "0.4.11"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2"
dependencies = [
"cfg-if 0.1.10",
]
@@ -886,9 +886,9 @@ checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b"
[[package]]
name = "pin-project-lite"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba36e0a6cc5a4c645073f4984f1ed55d09f5857d4de7c14550baa81a39ef5a17"
checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827"
[[package]]
name = "pin-utils"
@@ -1051,9 +1051,9 @@ checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "serde"
version = "1.0.118"
version = "1.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
checksum = "9bdd36f49e35b61d49efd8aa7fc068fd295961fd2286d0b2ee9a4c7a14e99cc3"
[[package]]
name = "serde_json"
@@ -1344,7 +1344,7 @@ checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3"
dependencies = [
"cfg-if 1.0.0",
"log",
"pin-project-lite 0.2.3",
"pin-project-lite 0.2.4",
"tracing-attributes",
"tracing-core",
]
@@ -18,12 +18,14 @@ async fn server(opts: config::Options) -> Result {
let public_head = warp::head().and(
warp::fs::dir(opts.root.clone())
.map(cache::control_headers)
.with(warp::trace::request())
.recover(rejection::handle_rejection),
);
let public_get_default = warp::get().and(
warp::fs::dir(opts.root.clone())
.map(cache::control_headers)
.with(warp::trace::request())
.recover(rejection::handle_rejection),
);
@@ -40,6 +42,7 @@ async fn server(opts: config::Options) -> Result {
.and(accept_encoding("br"))
.and(
warp::fs::dir(opts.root.clone())
.map(cache::control_headers)
.with(warp::trace::request())
.with(warp::compression::brotli(true))
.recover(rejection::handle_rejection),
@@ -54,6 +57,7 @@ async fn server(opts: config::Options) -> Result {
.and(accept_encoding("deflate"))
.and(
warp::fs::dir(opts.root.clone())
.map(cache::control_headers)
.with(warp::trace::request())
.with(warp::compression::deflate(true))
.recover(rejection::handle_rejection),
@@ -68,6 +72,7 @@ async fn server(opts: config::Options) -> Result {
.and(accept_encoding("gzip"))
.and(
warp::fs::dir(opts.root.clone())
.map(cache::control_headers)
.with(warp::trace::request())
.with(warp::compression::gzip(true))
.recover(rejection::handle_rejection),
@@ -0,0 +1,41 @@
const CACHE_EXT_ONE_HOUR: [&'static str; 4] = ["atom", "json", "rss", "xml"];
const CACHE_EXT_ONE_YEAR: [&'static str; 30] = [
"bmp", "bz2", "css", "map", "doc", "gif", "gz", "htc", "ico", "jpg", "mp3", "mp4", "ogg",
"ogv", "pdf", "png", "rar", "tar", "tgz", "wav", "weba", "webm", "webp", "woff", "zip", "jpeg",
"js", "mjs", "rtf", "woff2",
];
pub fn control_headers(res: warp::fs::File) -> warp::reply::WithHeader<warp::fs::File> {
let mut max_age = 60 * 60 * 24 as u64;
if let Some(ext) = res.path().extension() {
if let Some(ext) = ext.to_str() {
if CACHE_EXT_ONE_YEAR.iter().any(|n| *n == ext) {
max_age = 60 * 60 * 24 * 365;
}
if CACHE_EXT_ONE_HOUR.iter().any(|n| *n == ext) {
max_age = 60 * 60;
}
}
}
warp::reply::with_header(
res,
"cache-control",
[
"public, max-age=".to_string(),
duration(max_age).to_string(),
]
.concat(),
)
}
fn duration(n: u64) -> u32 {
std::cmp::min(n.clone(), u32::MAX as u64) as u32
}
@@ -1,3 +1,4 @@
pub mod cache;
pub mod config;
pub mod helpers;
pub mod logger;