use std::sync::Arc;
use axum::{
extract::{Request, State},
http::{StatusCode, header},
response::IntoResponse,
};
use crate::JsonRpc;
pub async fn handler(State(json_rpc): State<Arc<JsonRpc>>, request: Request) -> impl IntoResponse {
let bytes = match axum::body::to_bytes(request.into_body(), 10 * 1024 * 1024).await {
Ok(b) => b,
Err(e) => {
tracing::error!("Failed to read request body: {}", e);
return error_response(
StatusCode::BAD_REQUEST,
r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#,
);
}
};
let json_str = match String::from_utf8(bytes.to_vec()) {
Ok(s) => s,
Err(_) => {
tracing::error!("Invalid UTF-8 in request body");
return error_response(
StatusCode::BAD_REQUEST,
r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#,
);
}
};
tracing::debug!("Processing JSON-RPC request: {}", json_str);
match json_rpc.call(&json_str).await {
Some(response_json) => {
tracing::debug!("Sending JSON-RPC response: {}", response_json);
success_response(&response_json)
}
None => {
tracing::debug!("Notification processed - no response needed");
StatusCode::NO_CONTENT.into_response()
}
}
}
fn success_response(json: &str) -> axum::response::Response {
(
StatusCode::OK,
[(header::CONTENT_TYPE, "application/json")],
json.to_string(),
)
.into_response()
}
fn error_response(status: StatusCode, json: &str) -> axum::response::Response {
(
status,
[(header::CONTENT_TYPE, "application/json")],
json.to_string(),
)
.into_response()
}