1use crate::{
2 policy::{content::ContentPolicy, record::RecordPolicy},
3 services::CoreService,
4};
5use axum::{body::Body, http::Request, Router};
6use std::{path::PathBuf, sync::Arc};
7use tower::ServiceBuilder;
8use tower_http::{
9 cors::{Any, CorsLayer},
10 services::ServeDir,
11 trace::{DefaultMakeSpan, DefaultOnResponse, TraceLayer},
12 LatencyUnit,
13};
14use tracing::{Level, Span};
15use url::Url;
16
17pub mod v1;
18
19#[cfg(feature = "debug")]
20pub mod debug;
21
22pub fn create_router(
24 content_base_url: Url,
25 core: CoreService,
26 temp_dir: PathBuf,
27 files_dir: PathBuf,
28 content_policy: Option<Arc<dyn ContentPolicy>>,
29 record_policy: Option<Arc<dyn RecordPolicy>>,
30) -> Router {
31 let router = Router::new();
32 #[cfg(feature = "debug")]
33 let router = router.nest("/debug", debug::Config::new(core.clone()).into_router());
34 router
35 .nest(
36 "/v1",
37 v1::create_router(
38 content_base_url,
39 core,
40 temp_dir,
41 files_dir.clone(),
42 content_policy,
43 record_policy,
44 ),
45 )
46 .nest_service("/content", ServeDir::new(files_dir))
47 .layer(
48 ServiceBuilder::new()
49 .layer(
50 TraceLayer::new_for_http()
51 .make_span_with(DefaultMakeSpan::new().include_headers(true))
52 .on_request(|request: &Request<Body>, _span: &Span| {
53 tracing::info!("starting {} {}", request.method(), request.uri().path())
54 })
55 .on_response(
56 DefaultOnResponse::new()
57 .level(Level::INFO)
58 .latency_unit(LatencyUnit::Micros),
59 ),
60 )
61 .layer(
62 CorsLayer::new()
63 .allow_origin(Any)
64 .allow_methods([axum::http::Method::GET, axum::http::Method::POST])
65 .allow_headers([
66 axum::http::header::CONTENT_TYPE,
67 axum::http::header::ACCEPT,
68 ]),
69 ),
70 )
71}