Merge pull request #480 from vbrandl/feature/ructe-static
Use ructe static file support to serve static files with hashes and caching
This commit is contained in:
commit
633873814b
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -880,6 +880,7 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"git2",
|
"git2",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"mime",
|
||||||
"number_prefix",
|
"number_prefix",
|
||||||
"openssl-probe",
|
"openssl-probe",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
@ -1647,6 +1648,7 @@ dependencies = [
|
|||||||
"bytecount",
|
"bytecount",
|
||||||
"itertools",
|
"itertools",
|
||||||
"md5",
|
"md5",
|
||||||
|
"mime",
|
||||||
"nom",
|
"nom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ dotenv = "0.15.0"
|
|||||||
futures = "0.3.23"
|
futures = "0.3.23"
|
||||||
git2 = "0.15.0"
|
git2 = "0.15.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
mime = "0.3"
|
||||||
number_prefix = "0.4.0"
|
number_prefix = "0.4.0"
|
||||||
openssl-probe = "0.1.5"
|
openssl-probe = "0.1.5"
|
||||||
reqwest = "0.11.11"
|
reqwest = "0.11.11"
|
||||||
@ -36,7 +37,7 @@ tracing-log = "0.1.3"
|
|||||||
tracing-subscriber = { version = "0.3.15", features = ["registry", "env-filter"] }
|
tracing-subscriber = { version = "0.3.15", features = ["registry", "env-filter"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
ructe = "0.14.2"
|
ructe = { version = "0.14.2", features = ["mime03"] }
|
||||||
vergen = { version = "7.3.1", default-features = false, features = ["git"] }
|
vergen = { version = "7.3.1", default-features = false, features = ["git"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
5
build.rs
5
build.rs
@ -8,5 +8,8 @@ fn main() -> Result<(), RucteError> {
|
|||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
*config.git_mut().sha_kind_mut() = ShaKind::Short;
|
*config.git_mut().sha_kind_mut() = ShaKind::Short;
|
||||||
vergen(config).expect("Unable to generate static repo info");
|
vergen(config).expect("Unable to generate static repo info");
|
||||||
Ructe::from_env()?.compile_templates("templates")
|
let mut ructe = Ructe::from_env()?;
|
||||||
|
let mut statics = ructe.statics()?;
|
||||||
|
statics.add_files("static")?;
|
||||||
|
ructe.compile_templates("templates")
|
||||||
}
|
}
|
||||||
|
31
src/lib.rs
31
src/lib.rs
@ -23,7 +23,7 @@ use crate::{
|
|||||||
config::Settings,
|
config::Settings,
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
service::{Bitbucket, FormService, GitHub, Gitlab, Service, Sourcehut},
|
service::{Bitbucket, FormService, GitHub, Gitlab, Service, Sourcehut},
|
||||||
statics::{CLIENT, CSS, FAVICON, VERSION_INFO},
|
statics::{CLIENT, VERSION_INFO},
|
||||||
template::{RepoGeneratorInfo, RepoInfo},
|
template::{RepoGeneratorInfo, RepoInfo},
|
||||||
};
|
};
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
@ -46,6 +46,7 @@ use std::{
|
|||||||
sync::atomic::Ordering,
|
sync::atomic::Ordering,
|
||||||
time::{Duration, SystemTime},
|
time::{Duration, SystemTime},
|
||||||
};
|
};
|
||||||
|
use templates::statics::{self as template_statics, StaticFile};
|
||||||
use tracing::Instrument;
|
use tracing::Instrument;
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/templates.rs"));
|
include!(concat!(env!("OUT_DIR"), "/templates.rs"));
|
||||||
@ -470,14 +471,32 @@ async fn async_p404(repo_count: web::Data<AtomicUsize>) -> Result<HttpResponse>
|
|||||||
p404(repo_count)
|
p404(repo_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/tacit-css.min.css")]
|
/// A duration to add to current time for a far expires header.
|
||||||
async fn css() -> HttpResponse {
|
static FAR: Duration = Duration::from_secs(180 * 24 * 60 * 60);
|
||||||
HttpResponse::Ok().content_type("text/css").body(CSS)
|
|
||||||
|
#[get("/static/{filename}")]
|
||||||
|
async fn static_file(
|
||||||
|
path: web::Path<String>,
|
||||||
|
repo_count: web::Data<AtomicUsize>,
|
||||||
|
) -> Result<HttpResponse> {
|
||||||
|
StaticFile::get(&path)
|
||||||
|
.map(|data| {
|
||||||
|
let far_expires = SystemTime::now() + FAR;
|
||||||
|
HttpResponse::Ok()
|
||||||
|
.insert_header(Expires(far_expires.into()))
|
||||||
|
.content_type(data.mime.clone())
|
||||||
|
.body(data.content)
|
||||||
|
})
|
||||||
|
.map(Result::Ok)
|
||||||
|
.unwrap_or_else(|| p404(repo_count))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/favicon.ico")]
|
#[get("/favicon.ico")]
|
||||||
async fn favicon32() -> HttpResponse {
|
async fn favicon32() -> HttpResponse {
|
||||||
HttpResponse::Ok().content_type("image/png").body(FAVICON)
|
let data = &template_statics::favicon32_png;
|
||||||
|
HttpResponse::Ok()
|
||||||
|
.content_type(data.mime.clone())
|
||||||
|
.body(data.content)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start_server(listener: TcpListener, settings: Settings) -> std::io::Result<Server> {
|
async fn start_server(listener: TcpListener, settings: Settings) -> std::io::Result<Server> {
|
||||||
@ -494,7 +513,7 @@ async fn start_server(listener: TcpListener, settings: Settings) -> std::io::Res
|
|||||||
.wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
|
.wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
|
||||||
.service(index)
|
.service(index)
|
||||||
.service(health_check)
|
.service(health_check)
|
||||||
.service(css)
|
.service(static_file)
|
||||||
.service(favicon32)
|
.service(favicon32)
|
||||||
.service(generate)
|
.service(generate)
|
||||||
.default_service(web::to(async_p404));
|
.default_service(web::to(async_p404));
|
||||||
|
@ -7,8 +7,6 @@ pub(crate) const VERSION_INFO: VersionInfo = VersionInfo {
|
|||||||
commit: env!("VERGEN_GIT_SHA_SHORT"),
|
commit: env!("VERGEN_GIT_SHA_SHORT"),
|
||||||
version: env!("CARGO_PKG_VERSION"),
|
version: env!("CARGO_PKG_VERSION"),
|
||||||
};
|
};
|
||||||
pub(crate) const CSS: &str = include_str!("../static/tacit-css.min.css");
|
|
||||||
pub(crate) const FAVICON: &[u8] = include_bytes!("../static/favicon32.png");
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub(crate) static ref CLIENT: reqwest::Client = reqwest::Client::new();
|
pub(crate) static ref CLIENT: reqwest::Client = reqwest::Client::new();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@use super::statics::*;
|
||||||
@use crate::statics::VersionInfo;
|
@use crate::statics::VersionInfo;
|
||||||
|
|
||||||
@(title: &str, header: &str, content: Content, version_info: VersionInfo, repo_count: usize)
|
@(title: &str, header: &str, content: Content, version_info: VersionInfo, repo_count: usize)
|
||||||
@ -9,7 +10,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="keywords" content="Hits-of-Code, GitHub, Badge" />
|
<meta name="keywords" content="Hits-of-Code, GitHub, Badge" />
|
||||||
<meta name="description" content="Hits-of-Code Badges for Git repositories" />
|
<meta name="description" content="Hits-of-Code Badges for Git repositories" />
|
||||||
<link rel="stylesheet" href="/tacit-css.min.css" />
|
<link rel="stylesheet" href="/static/@tacit_css_min_css.name" />
|
||||||
<title>@title</title>
|
<title>@title</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -14,18 +14,3 @@ async fn favicon() {
|
|||||||
|
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
|
||||||
async fn tacit_css() {
|
|
||||||
let test_app = util::spawn_app().await;
|
|
||||||
|
|
||||||
let client = awc::Client::default();
|
|
||||||
|
|
||||||
let response = client
|
|
||||||
.get(&format!("{}/tacit-css.min.css", test_app.address))
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.expect("Failed to execute request");
|
|
||||||
|
|
||||||
assert!(response.status().is_success());
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user