1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
macro_rules! response {
($path:literal, $content_type:expr) => {{
use actix_web::http::header::{ContentType, HeaderValue};
use actix_web::{HttpRequest, HttpResponse};
use once_cell::sync::Lazy;
use ring::digest;
|req: HttpRequest| async move {
static BYTES: &[u8] = include_bytes!(concat!("../frontend/", $path));
static ETAG: Lazy<String> = Lazy::new(|| {
let digest = digest::digest(&digest::SHA256, BYTES);
let mut digest = data_encoding::BASE64URL.encode(digest.as_ref());
digest.reserve(2);
digest.insert(0, '"');
digest.push('"');
digest
});
let header = req.headers().get("If-None-Match");
if header.map(HeaderValue::as_bytes) == Some(ETAG.as_bytes()) {
HttpResponse::NotModified().finish()
} else {
HttpResponse::Ok()
.content_type($content_type)
.append_header(("ETag", ETAG.as_str()))
.body(BYTES)
}
}
}};
}
macro_rules! html {
($path:literal) => {
crate::frontend::response!($path, ContentType::html())
};
}
macro_rules! png {
($path:literal) => {
crate::frontend::response!($path, ContentType::png())
};
}
pub(crate) use {html, png, response};