use super::authorization::{bearer_is_authorized, ip_is_authorized, key_is_authorized}; use super::errors::FrontendResult; use crate::{app::Web3ProxyApp, jsonrpc::JsonRpcRequestEnum}; use axum::extract::Path; use axum::headers::authorization::Bearer; use axum::headers::{Authorization, Origin, Referer, UserAgent}; use axum::TypedHeader; use axum::{response::IntoResponse, Extension, Json}; use axum_client_ip::ClientIp; use std::sync::Arc; use tracing::{error_span, Instrument}; pub async fn proxy_web3_rpc( Extension(app): Extension>, bearer: Option>>, ClientIp(ip): ClientIp, Json(payload): Json, origin: Option>, referer: Option>, user_agent: Option>, ) -> FrontendResult { let request_span = error_span!("request", %ip, ?referer, ?user_agent); let (authorized_request, _semaphore) = if let Some(TypedHeader(Authorization(bearer))) = bearer { let origin = origin.map(|x| x.0); let referer = referer.map(|x| x.0); let user_agent = user_agent.map(|x| x.0); bearer_is_authorized(&app, bearer, ip, origin, referer, user_agent) .instrument(request_span.clone()) .await? } else { ip_is_authorized(&app, ip) .instrument(request_span.clone()) .await? }; let request_span = error_span!("request", ?authorized_request); let authorized_request = Arc::new(authorized_request); let f = tokio::spawn(async move { app.proxy_web3_rpc(authorized_request, payload) .instrument(request_span) .await }); let response = f.await.expect("joinhandle should always work")?; Ok(Json(&response).into_response()) } pub async fn proxy_web3_rpc_with_key( Extension(app): Extension>, ClientIp(ip): ClientIp, Json(payload): Json, origin: Option>, referer: Option>, user_agent: Option>, Path(user_key): Path, ) -> FrontendResult { let user_key = user_key.parse()?; let request_span = error_span!("request", %ip, ?referer, ?user_agent); // TODO: this should probably return the user_key_id instead? or maybe both? let (authorized_request, _semaphore) = key_is_authorized( &app, user_key, ip, origin.map(|x| x.0), referer.map(|x| x.0), user_agent.map(|x| x.0), ) .instrument(request_span.clone()) .await?; let request_span = error_span!("request", ?authorized_request); let authorized_request = Arc::new(authorized_request); let f = tokio::spawn(async move { app.proxy_web3_rpc(authorized_request, payload) .instrument(request_span) .await }); let response = f.await.expect("JoinHandle should always work")?; Ok(Json(&response).into_response()) }