diff --git a/Cargo.lock b/Cargo.lock index 0a9aa8fd44fa95474373dabce0153aeb57aec46e..25416302598dc1c7e1a148756912f628eff165b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -260,6 +260,17 @@ dependencies = [ "libc", ] +[[package]] +name = "async-recursion" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.2", +] + [[package]] name = "async-trait" version = "0.1.67" @@ -574,10 +585,11 @@ checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" [[package]] name = "drone" -version = "0.2.3" +version = "0.2.4" dependencies = [ "actix-cors", "actix-web", + "async-recursion", "config", "humantime", "lru_time_cache", diff --git a/Cargo.toml b/Cargo.toml index 29774001cf9debe8db89a45e64c3ae9226e4814c..65e7a96c8ba5c8cb8c49db4388088d5b222d58e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "drone" -version = "0.2.3" +version = "0.2.4" edition = "2021" authors = ["Deathwing <hi@deathwing.me>"] description = "A caching reverse-proxy application for the Hive blockchain." @@ -17,3 +17,4 @@ humantime = "2.1.0" config = "0.13.3" serde_with = "2.3.1" actix-cors = "0.6.4" +async-recursion = "1.0.5" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d9bf40cb289acfe7e44099f657ac9a623c164823..ee562699c2b5230babec0226cc769e3db88e0381 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use actix_cors::Cors; use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer, Responder}; +use async_recursion::async_recursion; use config::Config; use lru_time_cache::LruCache; use reqwest::{Client, ClientBuilder}; @@ -113,6 +114,7 @@ impl Endpoints { } } +#[async_recursion] async fn handle_request( request: &APIRequest, data: &web::Data<AppData>, @@ -120,7 +122,25 @@ async fn handle_request( ) -> Result<APICallResponse, ErrorStructure> { // Convert the call to a struct. let client = data.webclient.clone(); - // If there's a single call, just forward it. + let method = request.method.as_str(); + + if method == "call" { + if let Some(params) = request.params.as_array() { + if params.len() > 2 { + if let Some(method) = params[0].as_str() { + let format_new_method = format!("{}.{}", method, params[1].as_str().unwrap()); + let new_params = params[2].clone(); + let new_request = APIRequest { + jsonrpc: "2.0".to_string(), + id: request.id, + method: format_new_method, + params: new_params, + }; + return handle_request(&new_request, data, client_ip).await; + } + } + } + } // Get humantime for logging. let human_timestamp = humantime::format_rfc3339_seconds(std::time::SystemTime::now()); @@ -129,7 +149,8 @@ async fn handle_request( human_timestamp, client_ip, request.method, request.params, ); println!("{}", formatted_log); - let method = request.method.as_str(); + + // Pick the endpoints depending on the method. let endpoints = match method { // HAF @@ -167,6 +188,7 @@ async fn handle_request( "condenser_api.get_comment_discussions_by_payout" => Endpoints::HIVEMIND, "condenser_api.get_replies_by_last_update" => Endpoints::HIVEMIND, "condenser_api.get_reblogged_by" => Endpoints::HIVEMIND, + "database_api.find_comments" => Endpoints::HIVEMIND, _bridge_endpoint if method.starts_with("bridge.") => Endpoints::HIVEMIND, _follow_api_endpoint if method.starts_with("follow_api.") => Endpoints::HIVEMIND, // Remove when beem is updated. (Deprecated) _tags_api_endpoint if method.starts_with("tags_api.") => Endpoints::HIVEMIND, // Remove when beem is updated. (Deprecated)