Compare commits
2 commits
48dd31ec38
...
cc4f3669c5
Author | SHA1 | Date | |
---|---|---|---|
Emi Simpson | cc4f3669c5 | ||
Emi Simpson | 9176a5a0b8 |
|
@ -21,4 +21,12 @@ lazy_static = { version = "1.4.0", optional = true }
|
||||||
# that supports OGP, the card will include a visual of their pronouns.
|
# that supports OGP, the card will include a visual of their pronouns.
|
||||||
ogp_images = ["rusttype", "image", "lazy_static"]
|
ogp_images = ["rusttype", "image", "lazy_static"]
|
||||||
|
|
||||||
default = ["ogp_images"]
|
# Several assets are unchanging static assets, which by default can be served directly
|
||||||
|
# from the binary. If so, these assets will be embeded into the binary and copied into
|
||||||
|
# memory when the binary runs. To improve performance, you may elect to serve these
|
||||||
|
# binaries using a webserver and reverse proxy. If you choose to do so, you may
|
||||||
|
# optionally disable this feature. Doing so will remove the --dump-static-assets feature
|
||||||
|
# flag, and will remove the ability to serve any static assets.
|
||||||
|
embed_static_assets = []
|
||||||
|
|
||||||
|
default = ["ogp_images", "embed_static_assets"]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pub mod ogp_images;
|
pub mod ogp_images;
|
||||||
pub mod contrast;
|
pub mod contrast;
|
||||||
|
pub mod statics;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
@ -148,6 +149,9 @@ async fn main() -> std::io::Result<()> {
|
||||||
.wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
|
.wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
|
||||||
.service(create_link);
|
.service(create_link);
|
||||||
|
|
||||||
|
let app = statics::STATIC_ASSETS.iter()
|
||||||
|
.fold(app, |app, asset| app.service(asset.generate_resource()));
|
||||||
|
|
||||||
#[cfg(feature = "ogp_images")]
|
#[cfg(feature = "ogp_images")]
|
||||||
let app = app
|
let app = app
|
||||||
.service(resource("/thumb.png") .to(handle_thumbnail_request))
|
.service(resource("/thumb.png") .to(handle_thumbnail_request))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#![cfg(feature = "ogp_images")]
|
#![cfg(feature = "ogp_images")]
|
||||||
|
|
||||||
use crate::contrast::generate_color_pair_rgba;
|
use crate::contrast::generate_color_pair_rgba;
|
||||||
|
use crate::statics;
|
||||||
|
|
||||||
use image::{DynamicImage, ImageBuffer, Pixel, Rgb, Rgba};
|
use image::{DynamicImage, ImageBuffer, Pixel, Rgb, Rgba};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
@ -9,9 +10,8 @@ use rusttype::{Font, Scale, point};
|
||||||
|
|
||||||
const SCALE: u32 = 400;
|
const SCALE: u32 = 400;
|
||||||
const FONT_SCALE: f32 = 250.0;
|
const FONT_SCALE: f32 = 250.0;
|
||||||
const FONT_DATA: &[u8] = include_bytes!("../assets/LeagueGothic.otf");
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref FONT: Font<'static> = Font::try_from_bytes(FONT_DATA)
|
static ref FONT: Font<'static> = Font::try_from_bytes(statics::FONT.bytes)
|
||||||
.expect("Invalid font data in build. This build and binary is invalid, and cannot be used.");
|
.expect("Invalid font data in build. This build and binary is invalid, and cannot be used.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
70
web/src/statics.rs
Normal file
70
web/src/statics.rs
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
use actix_web::http::StatusCode;
|
||||||
|
use actix_web::HttpResponse;
|
||||||
|
use actix_web::HttpRequest;
|
||||||
|
use actix_web::web::resource;
|
||||||
|
use actix_web::Resource;
|
||||||
|
|
||||||
|
/// Represents a single static asset
|
||||||
|
///
|
||||||
|
/// Each asset is embeded into the binary, and can be served under the
|
||||||
|
/// `/static/{filename}` route. All static assets should be embeded in this way, and can
|
||||||
|
/// be referenced from this module.
|
||||||
|
pub struct StaticAsset {
|
||||||
|
|
||||||
|
/// The filename of this asset relative to `:/web/assets/` and the `/static/` route
|
||||||
|
pub filename: &'static str,
|
||||||
|
|
||||||
|
/// The content of the file
|
||||||
|
pub bytes: &'static [u8],
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StaticAsset {
|
||||||
|
/// Generate a actix resource for serving this asset
|
||||||
|
///
|
||||||
|
/// The resource will handle requests at `/static/{filename}`. Caching headers are
|
||||||
|
/// applied to allow the content to be considered fresh up to one day, and are
|
||||||
|
/// validated against the crate version after that.
|
||||||
|
pub fn generate_resource(&self) -> Resource {
|
||||||
|
let bytes = self.bytes;
|
||||||
|
resource(format!("/static/{}", self.filename))
|
||||||
|
.to(move|req: HttpRequest| async move {
|
||||||
|
let mut response = HttpResponse::Ok();
|
||||||
|
response
|
||||||
|
.header("Etag", env!("CARGO_PKG_VERSION"))
|
||||||
|
.header("Cache-Control", "max-age=86400");
|
||||||
|
|
||||||
|
let req_etag = req.headers().get("If-None-Match");
|
||||||
|
match req_etag {
|
||||||
|
Some(etag) if etag == env!("CARGO_PKG_VERSION") => {
|
||||||
|
response.status(StatusCode::from_u16(304).unwrap()).finish()
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
response.body(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Generate a [`StaticAsset`] at compiletime from a filename.
|
||||||
|
#[cfg(any(feature = "embed_static_assets", feature = "ogp_images"))]
|
||||||
|
macro_rules! static_asset {
|
||||||
|
( $filename: expr ) => {
|
||||||
|
StaticAsset {
|
||||||
|
filename: $filename,
|
||||||
|
bytes: include_bytes!(concat!("../assets/", $filename)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The decorative font to be used for pronouns displayed at a very large size
|
||||||
|
#[cfg(any(feature = "embed_static_assets", feature = "ogp_images"))]
|
||||||
|
pub const FONT: StaticAsset = static_asset!("font.otf");
|
||||||
|
|
||||||
|
/// A list of static assets which should be served by the server
|
||||||
|
pub const STATIC_ASSETS: &[StaticAsset] = &[
|
||||||
|
#[cfg(any(feature = "embed_static_assets"))]
|
||||||
|
FONT,
|
||||||
|
];
|
Loading…
Reference in a new issue