summaryrefslogtreecommitdiff
path: root/src/cache.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cache.rs')
-rw-r--r--src/cache.rs42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/cache.rs b/src/cache.rs
new file mode 100644
index 0000000..680d9da
--- /dev/null
+++ b/src/cache.rs
@@ -0,0 +1,42 @@
+use std::borrow::Cow;
+
+use rocket::{
+ http::Header,
+ request::{self, FromRequest},
+ response::{self, Responder},
+ Request,
+};
+
+pub(crate) struct Etagged<'r, T>(pub T, pub Cow<'r, str>);
+
+impl<'r, 'o: 'r, T: Responder<'r, 'o>> Responder<'r, 'o> for Etagged<'o, T> {
+ fn respond_to(self, r: &'r Request<'_>) -> response::Result<'o> {
+ let mut resp = self.0.respond_to(r)?;
+ resp.set_header(Header::new("etag", self.1));
+ Ok(resp)
+ }
+}
+
+pub(crate) struct Immutable<T>(pub T);
+
+impl<'r, 'o: 'r, T: Responder<'r, 'o>> Responder<'r, 'o> for Immutable<T> {
+ fn respond_to(self, r: &'r Request<'_>) -> response::Result<'o> {
+ let mut resp = self.0.respond_to(r)?;
+ resp.set_header(Header::new("cache-control", "public, max-age=604800, immutable"));
+ Ok(resp)
+ }
+}
+
+pub(crate) struct IfNoneMatch<'r>(pub &'r str);
+
+#[async_trait]
+impl<'r> FromRequest<'r> for IfNoneMatch<'r> {
+ type Error = ();
+
+ async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
+ match req.headers().get_one("if-none-match") {
+ Some(h) => request::Outcome::Success(Self(h)),
+ None => request::Outcome::Forward(()),
+ }
+ }
+}