Skip to content
Snippets Groups Projects
Commit 4ee3a00b authored by DeathwingTheBoss's avatar DeathwingTheBoss
Browse files

- Increase default payload limit to 1KB

- Improve hived error handling/responses
- Adhere to JSONRPC 2.0 standard.
- Add more endpoints, default endpoints to correct places
parent 7af3ab37
No related branches found
No related tags found
No related merge requests found
...@@ -559,7 +559,7 @@ checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" ...@@ -559,7 +559,7 @@ checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
[[package]] [[package]]
name = "drone" name = "drone"
version = "0.1.5" version = "0.1.6"
dependencies = [ dependencies = [
"actix-web", "actix-web",
"config", "config",
......
[package] [package]
name = "drone" name = "drone"
version = "0.1.5" version = "0.1.6"
edition = "2021" edition = "2021"
authors = ["Deathwing <hi@deathwing.me>"] authors = ["Deathwing <hi@deathwing.me>"]
description = "A caching reverse-proxy application for the Hive blockchain." description = "A caching reverse-proxy application for the Hive blockchain."
......
...@@ -2,7 +2,7 @@ use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer, Responder}; ...@@ -2,7 +2,7 @@ use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer, Responder};
use config::Config; use config::Config;
use lru_time_cache::LruCache; use lru_time_cache::LruCache;
use reqwest::{Client, ClientBuilder}; use reqwest::{Client, ClientBuilder};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize, Serializer};
use serde_json::Value; use serde_json::Value;
use serde_with::{serde_as, DurationSeconds}; use serde_with::{serde_as, DurationSeconds};
use std::{sync::Mutex, time::Duration}; use std::{sync::Mutex, time::Duration};
...@@ -54,12 +54,30 @@ struct APIRequest { ...@@ -54,12 +54,30 @@ struct APIRequest {
params: Value, params: Value,
} }
#[derive(Debug, Deserialize)]
enum ErrorField {
Object(Value), // JSON from Hived
Message(String), // Custom message
}
impl Serialize for ErrorField {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
ErrorField::Object(json_value) => json_value.serialize(serializer),
ErrorField::Message(text) => text.serialize(serializer),
}
}
}
// Structure for the error response. // Structure for the error response.
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
struct ErrorStructure { struct ErrorStructure {
code: i32, code: i32,
message: String, message: String,
error: String, error: ErrorField,
} }
// Enum for the endpoints. // Enum for the endpoints.
...@@ -103,23 +121,21 @@ async fn handle_request( ...@@ -103,23 +121,21 @@ async fn handle_request(
human_timestamp, client_ip, request.method, request.params, human_timestamp, client_ip, request.method, request.params,
); );
println!("{}", formatted_log); println!("{}", formatted_log);
let method = request.method.as_str();
// Pick the endpoints depending on the method. // Pick the endpoints depending on the method.
let endpoints = match request.method.as_str() { let endpoints = match method {
// HAF // HAF
"condenser_api.get_block" => Endpoints::HAF, "condenser_api.get_block" => Endpoints::HAF,
"block_api.get_block_range" => Endpoints::HAF, "block_api.get_block_range" => Endpoints::HAF,
"condenser_api.get_block_range" => Endpoints::HAF, "condenser_api.get_block_range" => Endpoints::HAF,
// HAFAH // HAFAH
"account_history_api" => Endpoints::HAFAH, _ if method.starts_with("account_history_api.") => Endpoints::HAFAH,
"account_history_api.get_ops_in_block" => Endpoints::HAFAH,
"account_history_api.enum_virtual_ops" => Endpoints::HAFAH,
"account_history_api.get_transaction" => Endpoints::HAFAH,
"account_history_api.get_account_history" => Endpoints::HAFAH,
"condenser_api.get_ops_in_block" => Endpoints::HAFAH, "condenser_api.get_ops_in_block" => Endpoints::HAFAH,
"condenser_api.get_transaction" => Endpoints::HAFAH, "condenser_api.get_transaction" => Endpoints::HAFAH,
"condenser_api.get_account_history" => Endpoints::HAFAH, "condenser_api.get_account_history" => Endpoints::HAFAH,
"database_api.get_account_history" => Endpoints::HAFAH, "database_api.get_account_history" => Endpoints::HAFAH,
// HIVEMIND // HIVEMIND
_hive_endpoint if method.starts_with("hive.") => Endpoints::HIVEMIND,
"condenser_api.get_content_replies" => Endpoints::HIVEMIND, "condenser_api.get_content_replies" => Endpoints::HIVEMIND,
"condenser_api.get_account_votes" => Endpoints::HIVEMIND, "condenser_api.get_account_votes" => Endpoints::HIVEMIND,
"condenser_api.get_followers" => Endpoints::HIVEMIND, "condenser_api.get_followers" => Endpoints::HIVEMIND,
...@@ -143,6 +159,7 @@ async fn handle_request( ...@@ -143,6 +159,7 @@ async fn handle_request(
"condenser_api.get_comment_discussions_by_payout" => Endpoints::HIVEMIND, "condenser_api.get_comment_discussions_by_payout" => Endpoints::HIVEMIND,
"condenser_api.get_replies_by_last_update" => Endpoints::HIVEMIND, "condenser_api.get_replies_by_last_update" => Endpoints::HIVEMIND,
"condenser_api.get_reblogged_by" => Endpoints::HIVEMIND, "condenser_api.get_reblogged_by" => Endpoints::HIVEMIND,
_bridge_endpoint if method.starts_with("bridge.") => Endpoints::HIVEMIND,
"follow_api" => Endpoints::HIVEMIND, "follow_api" => Endpoints::HIVEMIND,
"tags_api" => Endpoints::HIVEMIND, "tags_api" => Endpoints::HIVEMIND,
_anything_else => Endpoints::HAF, _anything_else => Endpoints::HAF,
...@@ -172,7 +189,7 @@ async fn handle_request( ...@@ -172,7 +189,7 @@ async fn handle_request(
return Err(ErrorStructure { return Err(ErrorStructure {
code: 1000, code: 1000,
message: format!("Unable to send request to endpoint."), message: format!("Unable to send request to endpoint."),
error: err.to_string(), error: ErrorField::Message(err.to_string()),
}) })
} }
}; };
...@@ -182,7 +199,7 @@ async fn handle_request( ...@@ -182,7 +199,7 @@ async fn handle_request(
return Err(ErrorStructure { return Err(ErrorStructure {
code: 2000, code: 2000,
message: format!("Received an invalid response from the endpoint."), message: format!("Received an invalid response from the endpoint."),
error: err.to_string(), error: ErrorField::Message(err.to_string()),
}) })
} }
}; };
...@@ -192,17 +209,24 @@ async fn handle_request( ...@@ -192,17 +209,24 @@ async fn handle_request(
return Err(ErrorStructure { return Err(ErrorStructure {
code: 3000, code: 3000,
message: format!("Unable to parse endpoint data."), message: format!("Unable to parse endpoint data."),
error: err.to_string(), error: ErrorField::Message(err.to_string()),
}) })
} }
}; };
if json_body["error"].is_object() {
return Err(ErrorStructure {
code: 4000,
message: format!("Endpoint returned an error."),
error: ErrorField::Object(json_body["error"].clone()),
});
}
if json_body["result"].is_array() && json_body["result"].as_array().unwrap().is_empty() if json_body["result"].is_array() && json_body["result"].as_array().unwrap().is_empty()
|| json_body["result"].is_null() || json_body["result"].is_null()
{ {
return Err(ErrorStructure { return Err(ErrorStructure {
code: 4000, code: 4000,
message: format!("Unable to parse endpoint data."), message: format!("Unable to parse endpoint data."),
error: "The endpoint returned an empty result.".to_string(), error: ErrorField::Message("The endpoint returned an empty result.".to_string()),
}); });
} }
...@@ -237,9 +261,9 @@ async fn api_call( ...@@ -237,9 +261,9 @@ async fn api_call(
Ok(ip) => ip, Ok(ip) => ip,
Err(_) => { Err(_) => {
return HttpResponse::InternalServerError().json(ErrorStructure { return HttpResponse::InternalServerError().json(ErrorStructure {
code: 9999, code: -32000,
message: "Internal Server Error".to_string(), message: "Internal Server Error".to_string(),
error: "Invalid Cloudflare Proxy Header.".to_string(), error: ErrorField::Message("Invalid Cloudflare Proxy Header.".to_string()),
}) })
} }
}; };
...@@ -339,7 +363,7 @@ async fn main() -> std::io::Result<()> { ...@@ -339,7 +363,7 @@ async fn main() -> std::io::Result<()> {
App::new() App::new()
.app_data(web::JsonConfig::default() .app_data(web::JsonConfig::default()
.content_type(|_| true) .content_type(|_| true)
.limit(512)) .limit(1024))
.app_data(_cache.clone()) .app_data(_cache.clone())
.route("/", web::get().to(index)) .route("/", web::get().to(index))
.route("/", web::post().to(api_call)) .route("/", web::post().to(api_call))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment