1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
pub mod api_token;
pub mod context;
pub mod endpoints;
pub mod errors;
pub mod genesis_block;
pub mod result;

use warp::{Filter, Rejection, Reply};

const V0_REQUEST_TRACE_NAME: &str = "v0_request";

pub async fn filter(
    ctx: context::SharedContext,
    enable_api_tokens: bool,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
    let api_root = warp::path!("api" / ..);

    let v0_root = warp::path!("v0" / ..);
    let service_version_root = warp::path!("vit-version" / ..);
    // log request statistics
    let log = warp::filters::trace::trace(|info| {
        use http_zipkin::get_trace_context;
        use tracing::field::Empty;
        let span = tracing::span!(
            tracing::Level::DEBUG,
            "rest_api_request",
            method = %info.method(),
            path = info.path(),
            version = ?info.version(),
            remote_addr = Empty,
            trace_id = Empty,
            span_id = Empty,
            parent_span_id = Empty,
        );
        if let Some(remote_addr) = info.remote_addr() {
            span.record("remote_addr", remote_addr.to_string().as_str());
        }
        if let Some(trace_context) = get_trace_context(info.request_headers()) {
            span.record("trace_id", trace_context.trace_id().to_string().as_str());
            span.record("span_id", trace_context.span_id().to_string().as_str());
            if let Some(parent_span_id) = trace_context.parent_id() {
                span.record("parent_span_id", parent_span_id.to_string().as_str());
            }
        }
        span
    });

    let v0 = endpoints::filter(v0_root.boxed(), ctx.clone(), enable_api_tokens).await;

    let service_version =
        endpoints::service_version::filter(service_version_root.boxed(), ctx).await;

    api_root
        .and(v0.or(service_version))
        .with(warp::trace::named(V0_REQUEST_TRACE_NAME))
        .recover(errors::handle_rejection)
        .with(log)
}