split frontend code up
This commit is contained in:
parent
7e3e28fbc1
commit
8427004516
31
web3-proxy/src/frontend/errors.rs
Normal file
31
web3-proxy/src/frontend/errors.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use crate::jsonrpc::JsonRpcForwardedResponse;
|
||||||
|
use axum::{http::StatusCode, response::IntoResponse, Json};
|
||||||
|
use serde_json::value::RawValue;
|
||||||
|
use tracing::warn;
|
||||||
|
|
||||||
|
/// TODO: pretty 404 page? or us a json error fine?
|
||||||
|
pub async fn handler_404() -> impl IntoResponse {
|
||||||
|
let err = anyhow::anyhow!("nothing to see here");
|
||||||
|
|
||||||
|
handle_anyhow_error(err, Some(StatusCode::NOT_FOUND)).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// handle errors by converting them into something that implements `IntoResponse`
|
||||||
|
/// TODO: use this. i can't get https://docs.rs/axum/latest/axum/error_handling/index.html to work
|
||||||
|
pub async fn handle_anyhow_error(
|
||||||
|
err: anyhow::Error,
|
||||||
|
code: Option<StatusCode>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
// TODO: what id can we use? how do we make sure the incoming id gets attached to this?
|
||||||
|
let id = RawValue::from_string("0".to_string()).unwrap();
|
||||||
|
|
||||||
|
let err = JsonRpcForwardedResponse::from_anyhow_error(err, id);
|
||||||
|
|
||||||
|
warn!("Responding with error: {:?}", err);
|
||||||
|
|
||||||
|
let code = code.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
|
||||||
|
(code, Json(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// i think we want a custom result type. it has an anyhow result inside. if it impl IntoResponse I think we'll get this for free
|
29
web3-proxy/src/frontend/http.rs
Normal file
29
web3-proxy/src/frontend/http.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use crate::app::Web3ProxyApp;
|
||||||
|
use axum::{http::StatusCode, response::IntoResponse, Extension, Json};
|
||||||
|
use serde_json::json;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// a page for configuring your wallet with all the rpcs
|
||||||
|
/// TODO: check auth (from authp?) here
|
||||||
|
/// TODO: return actual html
|
||||||
|
pub async fn index() -> impl IntoResponse {
|
||||||
|
"Hello, World!"
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Very basic status page
|
||||||
|
pub async fn status(app: Extension<Arc<Web3ProxyApp>>) -> impl IntoResponse {
|
||||||
|
let app = app.0.as_ref();
|
||||||
|
|
||||||
|
let balanced_rpcs = app.get_balanced_rpcs();
|
||||||
|
let private_rpcs = app.get_private_rpcs();
|
||||||
|
let num_active_requests = app.get_active_requests().len();
|
||||||
|
|
||||||
|
// TODO: what else should we include? uptime? prometheus?
|
||||||
|
let body = json!({
|
||||||
|
"balanced_rpcs": balanced_rpcs,
|
||||||
|
"private_rpcs": private_rpcs,
|
||||||
|
"num_active_requests": num_active_requests,
|
||||||
|
});
|
||||||
|
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR, Json(body))
|
||||||
|
}
|
14
web3-proxy/src/frontend/http_proxy.rs
Normal file
14
web3-proxy/src/frontend/http_proxy.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use super::errors::handle_anyhow_error;
|
||||||
|
use crate::{app::Web3ProxyApp, jsonrpc::JsonRpcRequestEnum};
|
||||||
|
use axum::{http::StatusCode, response::IntoResponse, Extension, Json};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub async fn proxy_web3_rpc(
|
||||||
|
payload: Json<JsonRpcRequestEnum>,
|
||||||
|
app: Extension<Arc<Web3ProxyApp>>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
match app.0.proxy_web3_rpc(payload.0).await {
|
||||||
|
Ok(response) => (StatusCode::OK, Json(&response)).into_response(),
|
||||||
|
Err(err) => handle_anyhow_error(err, None).await.into_response(),
|
||||||
|
}
|
||||||
|
}
|
41
web3-proxy/src/frontend/mod.rs
Normal file
41
web3-proxy/src/frontend/mod.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/// this should move into web3-proxy once the basics are working
|
||||||
|
mod errors;
|
||||||
|
mod http;
|
||||||
|
mod http_proxy;
|
||||||
|
mod ws_proxy;
|
||||||
|
use axum::{
|
||||||
|
handler::Handler,
|
||||||
|
routing::{get, post},
|
||||||
|
Extension, Router,
|
||||||
|
};
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::app::Web3ProxyApp;
|
||||||
|
|
||||||
|
pub async fn run(port: u16, proxy_app: Arc<Web3ProxyApp>) -> anyhow::Result<()> {
|
||||||
|
// TODO: check auth (from authp?) here
|
||||||
|
// build our application with a route
|
||||||
|
let app = Router::new()
|
||||||
|
// `POST /` goes to `proxy_web3_rpc`
|
||||||
|
.route("/", post(http_proxy::proxy_web3_rpc))
|
||||||
|
// `websocket /` goes to `proxy_web3_ws`
|
||||||
|
.route("/", get(ws_proxy::websocket_handler))
|
||||||
|
// `GET /index.html` goes to `index`
|
||||||
|
.route("/index.html", get(http::index))
|
||||||
|
// `GET /status` goes to `status`
|
||||||
|
.route("/status", get(http::status))
|
||||||
|
.layer(Extension(proxy_app));
|
||||||
|
|
||||||
|
// 404 for any unknown routes
|
||||||
|
let app = app.fallback(errors::handler_404.into_service());
|
||||||
|
|
||||||
|
// run our app with hyper
|
||||||
|
// `axum::Server` is a re-export of `hyper::Server`
|
||||||
|
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
||||||
|
tracing::info!("listening on port {}", addr);
|
||||||
|
axum::Server::bind(&addr)
|
||||||
|
.serve(app.into_make_service())
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
/// this should move into web3-proxy once the basics are working
|
use crate::{
|
||||||
|
app::Web3ProxyApp,
|
||||||
|
jsonrpc::{JsonRpcForwardedResponse, JsonRpcForwardedResponseEnum, JsonRpcRequest},
|
||||||
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::ws::{Message, WebSocket, WebSocketUpgrade},
|
extract::ws::{Message, WebSocket, WebSocketUpgrade},
|
||||||
handler::Handler,
|
|
||||||
http::StatusCode,
|
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
routing::{get, post},
|
Extension,
|
||||||
Extension, Json, Router,
|
|
||||||
};
|
};
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
use futures::{
|
use futures::{
|
||||||
@ -13,64 +13,12 @@ use futures::{
|
|||||||
stream::{SplitSink, SplitStream, StreamExt},
|
stream::{SplitSink, SplitStream, StreamExt},
|
||||||
};
|
};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use serde_json::json;
|
|
||||||
use serde_json::value::RawValue;
|
use serde_json::value::RawValue;
|
||||||
use std::net::SocketAddr;
|
|
||||||
use std::str::from_utf8_mut;
|
use std::str::from_utf8_mut;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::{debug, error, info, warn};
|
use tracing::{debug, error, info};
|
||||||
|
|
||||||
use crate::{
|
pub async fn websocket_handler(
|
||||||
app::Web3ProxyApp,
|
|
||||||
jsonrpc::{
|
|
||||||
JsonRpcForwardedResponse, JsonRpcForwardedResponseEnum, JsonRpcRequest, JsonRpcRequestEnum,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub async fn run(port: u16, proxy_app: Arc<Web3ProxyApp>) -> anyhow::Result<()> {
|
|
||||||
// build our application with a route
|
|
||||||
let app = Router::new()
|
|
||||||
// `GET /` goes to `root`
|
|
||||||
.route("/", get(root))
|
|
||||||
// `POST /` goes to `proxy_web3_rpc`
|
|
||||||
.route("/", post(proxy_web3_rpc))
|
|
||||||
// `websocket /` goes to `proxy_web3_ws`
|
|
||||||
.route("/ws", get(websocket_handler))
|
|
||||||
// `GET /status` goes to `status`
|
|
||||||
.route("/status", get(status))
|
|
||||||
.layer(Extension(proxy_app));
|
|
||||||
|
|
||||||
// 404 for any unknown routes
|
|
||||||
let app = app.fallback(handler_404.into_service());
|
|
||||||
|
|
||||||
// run our app with hyper
|
|
||||||
// `axum::Server` is a re-export of `hyper::Server`
|
|
||||||
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
|
||||||
tracing::info!("listening on port {}", addr);
|
|
||||||
axum::Server::bind(&addr)
|
|
||||||
.serve(app.into_make_service())
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// a page for configuring your wallet with all the rpcs
|
|
||||||
/// TODO: check auth (from authp?) here
|
|
||||||
async fn root() -> impl IntoResponse {
|
|
||||||
"Hello, World!"
|
|
||||||
}
|
|
||||||
|
|
||||||
/// TODO: check auth (from authp?) here
|
|
||||||
async fn proxy_web3_rpc(
|
|
||||||
payload: Json<JsonRpcRequestEnum>,
|
|
||||||
app: Extension<Arc<Web3ProxyApp>>,
|
|
||||||
) -> impl IntoResponse {
|
|
||||||
match app.0.proxy_web3_rpc(payload.0).await {
|
|
||||||
Ok(response) => (StatusCode::OK, Json(&response)).into_response(),
|
|
||||||
Err(err) => _handle_anyhow_error(err, None).await.into_response(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn websocket_handler(
|
|
||||||
app: Extension<Arc<Web3ProxyApp>>,
|
app: Extension<Arc<Web3ProxyApp>>,
|
||||||
ws: WebSocketUpgrade,
|
ws: WebSocketUpgrade,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
@ -212,45 +160,3 @@ async fn write_web3_socket(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Very basic status page
|
|
||||||
async fn status(app: Extension<Arc<Web3ProxyApp>>) -> impl IntoResponse {
|
|
||||||
let app = app.0.as_ref();
|
|
||||||
|
|
||||||
let balanced_rpcs = app.get_balanced_rpcs();
|
|
||||||
let private_rpcs = app.get_private_rpcs();
|
|
||||||
let num_active_requests = app.get_active_requests().len();
|
|
||||||
|
|
||||||
// TODO: what else should we include? uptime? prometheus?
|
|
||||||
let body = json!({
|
|
||||||
"balanced_rpcs": balanced_rpcs,
|
|
||||||
"private_rpcs": private_rpcs,
|
|
||||||
"num_active_requests": num_active_requests,
|
|
||||||
});
|
|
||||||
|
|
||||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(body))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// TODO: pretty 404 page? or us a json error fine?
|
|
||||||
async fn handler_404() -> impl IntoResponse {
|
|
||||||
let err = anyhow::anyhow!("nothing to see here");
|
|
||||||
|
|
||||||
_handle_anyhow_error(err, Some(StatusCode::NOT_FOUND)).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// handle errors by converting them into something that implements `IntoResponse`
|
|
||||||
/// TODO: use this. i can't get https://docs.rs/axum/latest/axum/error_handling/index.html to work
|
|
||||||
async fn _handle_anyhow_error(err: anyhow::Error, code: Option<StatusCode>) -> impl IntoResponse {
|
|
||||||
// TODO: what id can we use? how do we make sure the incoming id gets attached to this?
|
|
||||||
let id = RawValue::from_string("0".to_string()).unwrap();
|
|
||||||
|
|
||||||
let err = JsonRpcForwardedResponse::from_anyhow_error(err, id);
|
|
||||||
|
|
||||||
warn!("Responding with error: {:?}", err);
|
|
||||||
|
|
||||||
let code = code.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
|
|
||||||
|
|
||||||
(code, Json(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// i think we want a custom result type. it has an anyhow result inside. it impl IntoResponse
|
|
Loading…
Reference in New Issue
Block a user