view src/cacheresponder.rs @ 77:fd0237049be0

Show paths instead of tags & apply rust fixes
author Lewin Bormann <lbo@spheniscida.de>
date Mon, 31 Jul 2023 09:31:37 +0200
parents 2ecb25f3adfe
children d3368a7142ef
line wrap: on
line source



use std::convert::Into;

use rocket::data::Data;
use rocket::http::Header;

use rocket::request::Request;
use rocket::response::Responder;
use rocket::route::Handler;
use rocket::route::Outcome;
use rocket::route::Route;

#[derive(Clone, Debug)]
pub struct CacheControl(String);

impl CacheControl {
    pub fn new<S: AsRef<str>>(policy: S) -> CacheControl {
        CacheControl(policy.as_ref().to_string())
    }
}

impl Into<Header<'_>> for CacheControl {
    fn into(self) -> Header<'static> {
        Header::new("cache-control", self.0)
    }
}

#[derive(Responder)]
pub struct CachedResponder<R> {
    inner: R,
    cachecontrol: CacheControl,
}

impl<'r, 'o: 'r, R: Responder<'r, 'o>> CachedResponder<R> {
    fn wrap(inner: R, policy: String) -> CachedResponder<R> {
        CachedResponder {
            inner: inner,
            cachecontrol: CacheControl(policy),
        }
    }
}

#[derive(Clone)]
pub struct CachedHandler<H: Clone> {
    inner: H,
    cachecontrol: CacheControl,
}

unsafe impl<H: Clone + Send> Send for CachedHandler<H> {}
unsafe impl<H: Clone + Sync> Sync for CachedHandler<H> {}

impl<H: Clone + Handler> CachedHandler<H> {
    pub fn wrap(inner: H, policy: CacheControl) -> CachedHandler<H> {
        CachedHandler {
            inner: inner,
            cachecontrol: policy,
        }
    }
}

impl<H: Clone + Handler + Into<Vec<Route>>> Into<Vec<Route>> for CachedHandler<H> {
    fn into(self) -> Vec<Route> {
        // bah
        let mut r = self.inner.clone().into();
        assert_eq!(r.len(), 1);
        r[0].handler = Box::new(self);
        r
    }
}

#[rocket::async_trait]
impl<H: Clone + Handler> Handler for CachedHandler<H> {
    async fn handle<'r>(&self, req: &'r Request<'_>, data: Data<'r>) -> Outcome<'r> {
        match self.inner.handle(req, data).await {
            Outcome::Success(mut resp) => {
                resp.set_header(Header::new("cache-control", self.cachecontrol.0.clone()));
                Outcome::Success(resp)
            }
            o => o,
        }
    }
}