mirror-server/src/main.rs

85 lines
2.0 KiB
Rust
Raw Normal View History

use axum::{
extract::{Host, OriginalUri, Json},
http::{header::HeaderMap, Method},
Router,
};
use clap::Parser;
2023-01-12 15:31:03 -05:00
use serde::Serialize;
use serde_json::{json, Value};
use std::collections::BTreeMap;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct CliArgs {
/// Port to run on.
#[arg(short, long, default_value_t = 8080)]
port: u16,
/// Listen to IP mask
#[arg(short, long, default_value = "0.0.0.0")]
ips: String,
}
2023-01-12 15:31:03 -05:00
#[derive(Serialize)]
struct EchoHeader {
name: String,
value: String,
}
#[derive(Serialize)]
struct EchoResponse {
method: String,
path: String,
host: String,
headers: BTreeMap<String, String>,
body: Value,
2023-01-12 15:31:03 -05:00
}
async fn echo_request(
method: Method,
original_uri: OriginalUri,
host: Host,
header_map: HeaderMap,
body: Option<Json<Value>>
) -> Json<EchoResponse> {
let method = method.to_string();
let host = host.0;
let path = original_uri.path().to_string();
let headers = header_map
.iter()
.map(|(name, value)| (name.to_string(), value.to_str().unwrap_or("").to_string()))
.collect();
// TODO: Logging the method and path.
2023-01-12 15:31:03 -05:00
let json_body = match body {
None => {
// TODO: Adding logging.
json!({"error": "Non-JSON request sent."})
},
Some(Json(value)) => value,
};
let response = EchoResponse {
method,
host,
path,
headers,
body: json_body,
};
Json(response)
2023-01-12 15:31:03 -05:00
}
#[tokio::main]
async fn main() {
let cli_args = CliArgs::parse();
let listen_on = (cli_args.ips, cli_args.port);
let listen_on = format!("{ip}:{port}", ip = listen_on.0, port = listen_on.1);
let app = Router::new().fallback(echo_request);
let listener = tokio::net::TcpListener::bind(&listen_on)
.await
.unwrap_or_else(|_| panic!("Attempted binding to {}", listen_on));
axum::serve(listener, app)
2023-01-12 15:31:03 -05:00
.await
.expect("Server should start");
}