Break out into using axum extractor.
Add support for JSON extraction.
This commit is contained in:
parent
2ed659e3ad
commit
6a7869a80c
|
@ -19,4 +19,5 @@ section = "web"
|
||||||
axum = "0.7"
|
axum = "0.7"
|
||||||
clap = { version = "4.4", features = ["derive"] }
|
clap = { version = "4.4", features = ["derive"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0.113"
|
||||||
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] }
|
||||||
|
|
|
@ -11,6 +11,7 @@ A simple server for mirroring HTTP requests for testing.
|
||||||
* Create a DEB package:
|
* Create a DEB package:
|
||||||
* Install cargo-deb: `cargo install cargo-deb`
|
* Install cargo-deb: `cargo install cargo-deb`
|
||||||
* Create the DEB package: `cargo deb`
|
* Create the DEB package: `cargo deb`
|
||||||
|
* Faster builds using [cargo-watch](https://watchexec.github.io/#cargo-watch): `cargo watch -x run`
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
|
@ -25,7 +26,8 @@ sudo dpkg -i "mirror-server-${VERSION}_amd64.deb"
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
* [ ] Migrate actix to axum for easier maintainability.
|
* [x] Migrate actix to axum for easier maintainability.
|
||||||
|
* [x] Add mirroring of JSON request.
|
||||||
* [ ] Add logging to server.
|
* [ ] Add logging to server.
|
||||||
* [ ] Add convenience path to access logging for a certain date / records.
|
* [ ] Add convenience path to access logging for a certain date / records.
|
||||||
* [ ] Dockerize mirror-server for easier distribution.
|
* [ ] Dockerize mirror-server for easier distribution.
|
||||||
|
|
57
src/main.rs
57
src/main.rs
|
@ -1,9 +1,11 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Json, Request},
|
extract::{Host, OriginalUri, Json},
|
||||||
|
http::{header::HeaderMap, Method},
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use serde_json::{json, Value};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
@ -30,29 +32,40 @@ struct EchoResponse {
|
||||||
path: String,
|
path: String,
|
||||||
host: String,
|
host: String,
|
||||||
headers: BTreeMap<String, String>,
|
headers: BTreeMap<String, String>,
|
||||||
|
body: Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EchoResponse {
|
async fn echo_request(
|
||||||
fn new(req: &Request) -> Self {
|
method: Method,
|
||||||
let req_uri = req.uri();
|
original_uri: OriginalUri,
|
||||||
let mut headers = BTreeMap::new();
|
host: Host,
|
||||||
for (header_name, header_value) in req.headers().iter() {
|
header_map: HeaderMap,
|
||||||
headers.insert(
|
body: Option<Json<Value>>
|
||||||
header_name.to_string(),
|
) -> Json<EchoResponse> {
|
||||||
header_value.to_str().unwrap_or("ERROR").to_string(),
|
let method = method.to_string();
|
||||||
);
|
let host = host.0;
|
||||||
}
|
let path = original_uri.path().to_string();
|
||||||
EchoResponse {
|
let headers = header_map
|
||||||
method: req.method().to_string(),
|
.iter()
|
||||||
path: req_uri.path().to_string(),
|
.map(|(name, value)| (name.to_string(), value.to_str().unwrap_or("").to_string()))
|
||||||
host: req_uri.host().unwrap_or("").to_string(),
|
.collect();
|
||||||
headers,
|
// TODO: Logging the method and path.
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn echo_request(request: Request) -> Json<EchoResponse> {
|
let json_body = match body {
|
||||||
Json(EchoResponse::new(&request))
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -64,7 +77,7 @@ async fn main() {
|
||||||
let app = Router::new().fallback(echo_request);
|
let app = Router::new().fallback(echo_request);
|
||||||
let listener = tokio::net::TcpListener::bind(&listen_on)
|
let listener = tokio::net::TcpListener::bind(&listen_on)
|
||||||
.await
|
.await
|
||||||
.expect(&format!("Attempted binding to {}", listen_on));
|
.unwrap_or_else(|_| panic!("Attempted binding to {}", listen_on));
|
||||||
axum::serve(listener, app)
|
axum::serve(listener, app)
|
||||||
.await
|
.await
|
||||||
.expect("Server should start");
|
.expect("Server should start");
|
||||||
|
|
Loading…
Reference in New Issue