warg_server/api/
mod.rs

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
22/// Creates the router for the API.
23pub 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}