bobashare_web/
static_routes.rs1use axum::response::IntoResponse;
4use hyper::{header, HeaderMap, StatusCode, Uri};
5use rust_embed::RustEmbed;
6use tracing::{event, instrument, Level};
7
8#[derive(RustEmbed)]
9#[folder = "static/"]
10struct Asset;
11
12#[instrument(skip(headers), fields(if_none_match = ?headers.get(header::IF_NONE_MATCH)))]
13pub async fn handler(uri: Uri, headers: HeaderMap) -> impl IntoResponse {
14 let path = uri.path().trim_start_matches('/');
15 event!(Level::DEBUG, ?path);
16
17 match Asset::get(path) {
18 None => {
19 event!(Level::WARN, path, "file not found");
20 (StatusCode::NOT_FOUND, "404 Not Found").into_response()
21 }
22 Some(f) => {
23 let sha256 = hex::encode(f.metadata.sha256_hash());
24 event!(Level::TRACE, sha256);
25 if cfg!(not(debug_assertions)) {
26 if let Some(tag) = headers.get(header::IF_NONE_MATCH) {
27 event!(Level::TRACE, ?tag);
28 let Ok(tag) = tag.to_str() else {
30 return (StatusCode::BAD_REQUEST, "invalid ETag").into_response();
31 };
32 if tag == sha256 {
33 return (StatusCode::NOT_MODIFIED, "").into_response();
34 }
35 }
36 }
37
38 let mimetype = f.metadata.mimetype();
39 event!(Level::DEBUG, ?sha256, ?mimetype);
40 (
41 [
42 (header::ACCESS_CONTROL_ALLOW_ORIGIN, "*".to_string()),
43 (header::CACHE_CONTROL, "no-cache".to_string()),
44 (header::CONTENT_TYPE, mimetype.to_string()),
45 (header::ETAG, sha256),
46 ],
47 f.data,
48 )
49 .into_response()
50 }
51 }
52}