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 std::str::from_utf8;
use xitca_http::body::ResponseBody;
use xitca_http::http;
use xitca_http::http::{HeaderName, HeaderValue, IntoResponse, Response};

type HttpStatusCode = http::StatusCode;
type XitcaRequest<E> = http::Request<http::RequestExt<E>>;

impl Handler {
    pub fn handle_xitca_request<E>(&self, req: XitcaRequest<E>) -> Response<ResponseBody> {
        self.handle(RequestAdapter { inner: req })
    }
}

struct RequestAdapter<E> {
    inner: XitcaRequest<E>,
}

impl<E> Request<Response<ResponseBody>> for RequestAdapter<E> {
    fn method(&self) -> &[u8] {
        self.inner.method().as_str().as_bytes()
    }

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

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

    fn response<'a>(
        self,
        code: StatusCode,
        response_headers: impl Iterator<Item = &'a Line>,
        body: Option<Bytes>,
    ) -> Response<ResponseBody> {
        let mut res = self.inner.into_response(
            body.map(ResponseBody::bytes)
                .unwrap_or_else(ResponseBody::empty),
        );
        let headers = res.headers_mut();
        response_headers.for_each(|line| {
            headers.append(
                HeaderName::from_static(from_utf8(line.key).unwrap()),
                HeaderValue::from_bytes(line.value.as_ref()).unwrap(),
            );
        });
        *res.status_mut() = HttpStatusCode::from_u16(code.into()).unwrap();
        res
    }
}