use std::sync::Arc;
use axum::extract::{Path, State};
use axum::http::{StatusCode, header};
use axum::response::{IntoResponse, Response};
use tracing::debug;
use acme_proxy_signer::Http01TokenStore;
#[derive(Clone)]
pub struct Http01Stores(pub Arc<Vec<Arc<dyn Http01TokenStore>>>);
pub async fn get_challenge_file(
State(stores): State<Http01Stores>,
Path(token): Path<String>,
) -> Response {
let mut unreadable = false;
let mut found = None;
for store in stores.0.iter() {
match store.lookup(&token).await {
Ok(Some(key_authorization)) => {
found = Some(key_authorization);
break;
}
Ok(None) => {}
Err(_) => unreadable = true,
}
}
match found {
Some(key_authorization) => {
debug!(event = "http_01_responder_served", outcome = "success", token = %token);
(
StatusCode::OK,
[(header::CONTENT_TYPE, "application/octet-stream")],
key_authorization,
)
.into_response()
}
None if unreadable => (
StatusCode::INTERNAL_SERVER_ERROR,
[(header::CONTENT_TYPE, "text/plain; charset=utf-8")],
"Internal Server Error",
)
.into_response(),
None => {
debug!(event = "http_01_responder_unknown_token", outcome = "failure", token = %token);
(
StatusCode::NOT_FOUND,
[(header::CONTENT_TYPE, "text/plain; charset=utf-8")],
"Not Found",
)
.into_response()
}
}
}