use std::fs;
use super::super::request::{Request, PathIter};
use super::super::response::HttpResponse;
use super::error::DispatchError;
pub async fn dispatch_request(
request: Request<'_>,
mut path: PathIter<'_>,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
Some("") => index(request),
Some("api") => super::api::dispatch(request, path).await,
Some("assets") => assets(request, path),
Some("auth") => super::auth::dispatch(request, path).await,
Some("health") => health(request, path),
Some("metrics") => super::metrics::dispatch(request, path).await,
Some("rfc8181") => rfc8181(request, path).await,
Some("rfc6492") => rfc6492(request, path).await,
Some("rrdp") => rrdp(request, path),
Some("stats") => super::stats::dispatch(request, path).await,
Some("ta") => ta(request, path),
Some("testbed.tal") => tal(request, path),
Some("testbed") => super::testbed::dispatch(request, path).await,
Some("ui") => ui(request, path),
_ => Ok(HttpResponse::not_found())
}
}
fn index(
request: Request<'_>
) -> Result<HttpResponse, DispatchError> {
request.check_get()?;
let (request, _) = request.proceed_unchecked();
request.empty()?;
Ok(HttpResponse::found("/ui"))
}
fn health(
request: Request<'_>, path: PathIter<'_>,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_unchecked();
request.empty()?;
Ok(HttpResponse::ok())
}
async fn rfc8181(
request: Request<'_>, path: PathIter<'_>
) -> Result<HttpResponse, DispatchError> {
let mut path = path.strip_trailing_slash();
let publisher = path.parse_next()?;
path.check_exhausted()?;
request.check_post()?;
let (request, _) = request.proceed_unchecked();
let (server, bytes) = request.read_rfc8181_bytes().await?;
Ok(HttpResponse::rfc8181(
server.krill().rfc8181(publisher, bytes)?
))
}
async fn rfc6492(
request: Request<'_>, path: PathIter<'_>
) -> Result<HttpResponse, DispatchError> {
let mut path = path.strip_trailing_slash();
let ca = path.parse_next()?;
path.check_exhausted()?;
request.check_post()?;
let user_agent = request.user_agent();
let (request, auth) = request.proceed_unchecked();
let (server, bytes) = request.read_rfc6492_bytes().await?;
Ok(HttpResponse::rfc6492(
server.krill().rfc6492(ca , bytes, user_agent, auth.actor())?
))
}
fn ta(
request: Request<'_>, mut path: PathIter<'_>
) -> Result<HttpResponse, DispatchError> {
match path.next() {
Some("ta.tal") => tal(request, path),
Some("ta.cer") => ta_cer(request, path),
_ => Ok(HttpResponse::not_found())
}
}
fn tal(
request: Request<'_>, path: PathIter<'_>
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_unchecked();
let server = request.empty()?;
Ok(HttpResponse::text(
server.krill().ta_cert_details()?.tal.to_string()
))
}
fn ta_cer(
request: Request<'_>, path: PathIter<'_>
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_unchecked();
let server = request.empty()?;
Ok(HttpResponse::cert(
server.krill().ta_cert_details()?.cert.to_bytes()
))
}
fn rrdp(
request: Request<'_>, path: PathIter<'_>
) -> Result<HttpResponse, DispatchError> {
request.check_get()?;
let (request, _) = request.proceed_unchecked();
let server = request.empty()?;
let Some(remaining) = path.remaining() else {
return Ok(HttpResponse::not_found())
};
let path = match server.krill().resolve_rrdp_request_path(remaining)? {
Some(path) => path,
None => {
return Ok(HttpResponse::not_found())
}
};
let cache_seconds = if remaining == "notification.xml" {
60
} else {
86400
};
let buffer = match fs::read(&path) {
Ok(file) => file,
Err(_) => {
return Ok(HttpResponse::not_found())
}
};
Ok(HttpResponse::xml_with_cache(buffer, cache_seconds))
}
fn ui(
request: Request<'_>, _path: PathIter<'_>
) -> Result<HttpResponse, DispatchError> {
request.check_get()?;
let (request, _) = request.proceed_unchecked();
let _server = request.empty()?;
Ok(HttpResponse::ok_with_body(
assets::INDEX.media_type,
assets::INDEX.content,
))
}
fn assets(
request: Request<'_>, mut path: PathIter<'_>
) -> Result<HttpResponse, DispatchError> {
let asset = {
let Some(next) = path.next() else {
return Ok(HttpResponse::not_found())
};
match assets::ASSETS.iter().find(|asset| {
asset.path == next
}) {
Some(asset) => asset,
None => return Ok(HttpResponse::not_found()),
}
};
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_unchecked();
let _server = request.empty()?;
Ok(HttpResponse::ok_with_body(
asset.media_type,
asset.content,
))
}
mod assets {
include!(concat!(env!("OUT_DIR"), "/ui_assets.rs"));
}