rustls_acme/
tower.rs

1use crate::ResolvesServerCertAcme;
2use http::{header, HeaderValue, Request, StatusCode};
3use std::sync::Arc;
4
5#[derive(Clone)]
6pub struct TowerHttp01ChallengeService(pub(crate) Arc<ResolvesServerCertAcme>);
7
8impl<B> tower_service::Service<Request<B>> for TowerHttp01ChallengeService {
9    type Response = http::Response<String>;
10    type Error = std::convert::Infallible;
11    type Future = std::future::Ready<Result<Self::Response, Self::Error>>;
12
13    fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), Self::Error>> {
14        std::task::Poll::Ready(Ok(()))
15    }
16
17    fn call(&mut self, req: Request<B>) -> Self::Future {
18        let mut response = http::Response::new(String::new());
19        *response.status_mut() = StatusCode::NOT_FOUND;
20        let Some((_, token)) = req.uri().path().rsplit_once('/') else {
21            return std::future::ready(Ok(response));
22        };
23        let Some(body) = self.0.get_http_01_key_auth(token) else {
24            return std::future::ready(Ok(response));
25        };
26        *response.status_mut() = StatusCode::OK;
27        *response.body_mut() = body;
28        response
29            .headers_mut()
30            .append(header::CONTENT_TYPE, HeaderValue::from_static("application/octet-stream"));
31        std::future::ready(Ok(response))
32    }
33}