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
59
60
use std::net::SocketAddr;

use axum::{http::StatusCode, routing::post, Json, Router};
use tracing::{error, info, span, warn};

/// Start the server.
pub async fn start() {
    let app = Router::new().route("/", post(post_handler));

    let port = 3000;
    let addr = SocketAddr::from(([127, 0, 0, 1], port));

    let listener = match tokio::net::TcpListener::bind(addr).await {
        Ok(listener) => listener,
        Err(e) => {
            error!("Failed to bind to port {}: {}", port, e);
            return;
        }
    };

    info!("Listening on port {}", port);

    if let Err(e) = axum::serve(listener, app).await {
        error!("Server error: {}", e);
    }
}

async fn post_handler(body: Json<dwn::data::Body>) -> StatusCode {
    for message in body.0.messages.iter() {
        span!(tracing::Level::INFO, "message", ?message);

        // Validate message
        if message.data.is_some() {
            match &message.descriptor.data_cid {
                Some(_) => {
                    // TODO: Validate data_cid
                }
                None => {
                    warn!("Message has data but dataCid is None");
                    return StatusCode::BAD_REQUEST;
                }
            };

            match &message.descriptor.data_format {
                Some(_) => {
                    // TODO: Validate data_format
                }
                None => {
                    warn!("Message has data but dataFormat is None");
                    return StatusCode::BAD_REQUEST;
                }
            };
        }

        // Process message
        info!("Received message: {:?}", message);
    }

    StatusCode::OK
}