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}