zip_static_handler 0.22.0

Static file handler from zip archive
Documentation
use crate::handler::Handler;
use crate::http::headers::Line;
use crate::http::request::Request;
use crate::http::response::StatusCode;
use bytes::Bytes;
use salvo::async_trait;
use salvo::http::{HeaderMap, HeaderName, HeaderValue};
use salvo::{Depot, FlowCtrl};
use std::str::from_utf8;

type HttpStatusCode = salvo::http::StatusCode;
type SalvoResponse = salvo::Response;
type SalvoRequest = salvo::Request;

struct RequestAdapter<'a> {
    request: &'a mut SalvoRequest,
    response: &'a mut SalvoResponse,
}

impl Request<()> for RequestAdapter<'_> {
    fn method(&self) -> &[u8] {
        self.request.method().as_str().as_bytes()
    }

    fn path(&self) -> &[u8] {
        self.request.uri().path().as_bytes()
    }

    fn first_header_value(&self, key: &'static [u8]) -> Option<&[u8]> {
        from_utf8(key)
            .ok()
            .and_then(|key| self.request.headers().get(key).map(|it| it.as_bytes()))
    }

    fn response<'a>(
        self,
        code: StatusCode,
        headers: impl Iterator<Item = &'a Line>,
        body: Option<Bytes>,
    ) {
        let status_code: HttpStatusCode = HttpStatusCode::from_u16(code.into()).unwrap();
        let mut map = HeaderMap::new();
        headers.for_each(|line| {
            if let Ok(name) = HeaderName::from_bytes(line.key)
                && let Ok(value) = HeaderValue::from_bytes(line.value.as_ref())
            {
                map.append(name, value);
            }
        });
        if let Some(bytes) = body {
            self.response.status_code = Some(status_code);
            self.response.set_headers(map);
            self.response.body(bytes);
        } else {
            self.response.status_code = Some(status_code);
            self.response.set_headers(map);
        }
    }
}

#[async_trait]
impl salvo::Handler for Handler {
    async fn handle(
        &self,
        request: &mut SalvoRequest,
        _depot: &mut Depot,
        response: &mut SalvoResponse,
        _ctrl: &mut FlowCtrl,
    ) {
        self.handle(RequestAdapter { request, response });
    }
}