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::{
|
||||
extract::ws::{Message, WebSocket, WebSocketUpgrade},
|
||||
handler::Handler,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{get, post},
|
||||
Extension, Json, Router,
|
||||
Extension,
|
||||
};
|
||||
use futures::SinkExt;
|
||||
use futures::{
|
||||
@ -13,64 +13,12 @@ use futures::{
|
||||
stream::{SplitSink, SplitStream, StreamExt},
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use serde_json::json;
|
||||
use serde_json::value::RawValue;
|
||||
use std::net::SocketAddr;
|
||||
use std::str::from_utf8_mut;
|
||||
use std::sync::Arc;
|
||||
use tracing::{debug, error, info, warn};
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
use crate::{
|
||||
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(
|
||||
pub async fn websocket_handler(
|
||||
app: Extension<Arc<Web3ProxyApp>>,
|
||||
ws: WebSocketUpgrade,
|
||||
) -> 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