diff --git a/Cargo.lock b/Cargo.lock index 6a386cddf66b522b28028b4a71fecf46cb2d3d84..d63d1466b1c40561fe4173322ed14d0213b09823 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -949,6 +949,7 @@ dependencies = [ "rusqlite", "serde", "serde_json", + "serde_path_to_error", "sha2", "structopt", "tokio", @@ -1292,6 +1293,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f6109f0506e20f7e0f910e51a0079acf41da8e0694e6442527c4ddf5a2b158" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index c26b2d35e97263af1c5bcef0dc947390c1413582..61b0ba43b97ad937cff7c868af92d65247eb22ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ regex = "1.5.4" rusqlite = { version = "0.25.3", features = ["sqlcipher"] } serde = { version = "1.0.126", features = ["derive"] } serde_json = "1.0.64" +serde_path_to_error = "0.1.4" sha2 = "0.9.5" structopt = { version = "0.3.22", features = ["color", "suggestions"] } tokio = { version = "1.9.0", features = ["full"] } diff --git a/src/error.rs b/src/error.rs index 07dcee51d90b66060db7c5a35d25ad3c66efa179..7dac4a7716fffa81bf39859ec270d2c30ca42a25 100644 --- a/src/error.rs +++ b/src/error.rs @@ -65,6 +65,16 @@ impl From<serde_json::Error> for Error { } } +impl From<serde_path_to_error::Error<serde_json::Error>> for Error { + fn from(err: serde_path_to_error::Error<serde_json::Error>) -> Error { + let msg = format!("JSON deserialization error {}", err); + Error { + code: StatusCode::BAD_REQUEST, + msg, + } + } +} + impl<T> From<std::sync::PoisonError<T>> for Error { fn from(err: std::sync::PoisonError<T>) -> Error { let msg = format!( diff --git a/src/warp_api.rs b/src/warp_api.rs index f5025001a68221fb2164ccf1ad714f39d8449b5a..2f6b3b7c8bf2ffdd32901a35e41bdf213bbf7635 100644 --- a/src/warp_api.rs +++ b/src/warp_api.rs @@ -1,11 +1,3 @@ -use crate::api_model::Bulk; -use crate::api_model::CreateEdge; -use crate::api_model::CreateItem; -use crate::api_model::GetEdges; -use crate::api_model::GetFile; -use crate::api_model::PayloadWrapper; -use crate::api_model::Search; -use crate::api_model::UpdateItem; use crate::command_line_interface; use crate::command_line_interface::CliOptions; use crate::error::Result; @@ -63,8 +55,8 @@ pub async fn run_server(cli_options: CliOptions) { let create_item = items_api .and(warp::path!(String / "create_item")) .and(warp::path::end()) - .and(warp::body::json()) - .map(move |owner: String, body: PayloadWrapper<CreateItem>| { + .and(warp::body::bytes()) + .map(move |owner: String, body: Bytes| { let cli = cli_options_arc_clone.deref(); let result = warp_endpoints::create_item(owner, init_db.deref(), body, cli); let result = result.map(|result| warp::reply::json(&result)); @@ -75,8 +67,8 @@ pub async fn run_server(cli_options: CliOptions) { let get_item = items_api .and(warp::path!(String / "get_item")) .and(warp::path::end()) - .and(warp::body::json()) - .map(move |owner: String, body: PayloadWrapper<String>| { + .and(warp::body::bytes()) + .map(move |owner: String, body: Bytes| { let result = warp_endpoints::get_item(owner, init_db.deref(), body); let result = result.map(|result| warp::reply::json(&result)); respond_with_result(result) @@ -86,8 +78,8 @@ pub async fn run_server(cli_options: CliOptions) { let update_item = items_api .and(warp::path!(String / "update_item")) .and(warp::path::end()) - .and(warp::body::json()) - .map(move |owner: String, body: PayloadWrapper<UpdateItem>| { + .and(warp::body::bytes()) + .map(move |owner: String, body: Bytes| { let result = warp_endpoints::update_item(owner, init_db.deref(), body); let result = result.map(|()| warp::reply::json(&serde_json::json!({}))); respond_with_result(result) @@ -97,8 +89,8 @@ pub async fn run_server(cli_options: CliOptions) { let get_edges = items_api .and(warp::path!(String / "get_edges")) .and(warp::path::end()) - .and(warp::body::json()) - .map(move |owner: String, body: PayloadWrapper<GetEdges>| { + .and(warp::body::bytes()) + .map(move |owner: String, body: Bytes| { let result = warp_endpoints::get_edges(owner, init_db.deref(), body); let result = result.map(|result| warp::reply::json(&result)); respond_with_result(result) @@ -108,8 +100,8 @@ pub async fn run_server(cli_options: CliOptions) { let create_edge = items_api .and(warp::path!(String / "create_edge")) .and(warp::path::end()) - .and(warp::body::json()) - .map(move |owner: String, body: PayloadWrapper<CreateEdge>| { + .and(warp::body::bytes()) + .map(move |owner: String, body: Bytes| { let result = warp_endpoints::create_edge(owner, init_db.deref(), body); let result = result.map(|result| warp::reply::json(&result)); respond_with_result(result) @@ -120,8 +112,8 @@ pub async fn run_server(cli_options: CliOptions) { let bulk_action = items_api .and(warp::path!(String / "bulk")) .and(warp::path::end()) - .and(warp::body::json()) - .map(move |owner: String, body: PayloadWrapper<Bulk>| { + .and(warp::body::bytes()) + .map(move |owner: String, body: Bytes| { let cli = cli_options_arc_clone.deref(); let result = warp_endpoints::bulk(owner, init_db.deref(), body, cli); let result = result.map(|value| warp::reply::json(&value)); @@ -132,8 +124,8 @@ pub async fn run_server(cli_options: CliOptions) { let delete_item = items_api .and(warp::path!(String / "delete_item")) .and(warp::path::end()) - .and(warp::body::json()) - .map(move |owner: String, body: PayloadWrapper<String>| { + .and(warp::body::bytes()) + .map(move |owner: String, body: Bytes| { let result = warp_endpoints::delete_item(owner, init_db.deref(), body); let result = result.map(|()| warp::reply::json(&serde_json::json!({}))); respond_with_result(result) @@ -143,8 +135,8 @@ pub async fn run_server(cli_options: CliOptions) { let search = items_api .and(warp::path!(String / "search")) .and(warp::path::end()) - .and(warp::body::json()) - .map(move |owner: String, body: PayloadWrapper<Search>| { + .and(warp::body::bytes()) + .map(move |owner: String, body: Bytes| { let result = warp_endpoints::search(owner, init_db.deref(), body); let result = result.map(|result| warp::reply::json(&result)); respond_with_result(result) @@ -172,8 +164,8 @@ pub async fn run_server(cli_options: CliOptions) { let get_file = file_api .and(warp::path!(String / "get_file")) .and(warp::path::end()) - .and(warp::body::json()) - .map(move |owner: String, body: PayloadWrapper<GetFile>| { + .and(warp::body::bytes()) + .map(move |owner: String, body: Bytes| { let result = warp_endpoints::get_file(owner, init_db.deref(), body); respond_with_result(result) }); diff --git a/src/warp_endpoints.rs b/src/warp_endpoints.rs index 6fb1ffae4f4dd91166e0d67cc754062d39eb0763..843f201bb8bba5f98e7b98966894f8b07044a3ac 100644 --- a/src/warp_endpoints.rs +++ b/src/warp_endpoints.rs @@ -33,6 +33,7 @@ use std::ops::Deref; use std::path::PathBuf; use std::sync::RwLock; use warp::http::status::StatusCode; +use warp::hyper::body::Bytes; // // Items API: @@ -41,8 +42,10 @@ use warp::http::status::StatusCode; pub fn get_item( owner: String, init_db: &RwLock<HashSet<String>>, - body: PayloadWrapper<String>, + body: Bytes, ) -> Result<Vec<Value>> { + let body = &mut serde_json::Deserializer::from_slice(body.deref()); + let body: PayloadWrapper<String> = serde_path_to_error::deserialize(body)?; let auth = body.auth; let payload = body.payload; let database_key = auth_to_database_key(auth)?; @@ -56,9 +59,11 @@ pub fn get_item( pub fn create_item( owner: String, init_db: &RwLock<HashSet<String>>, - body: PayloadWrapper<CreateItem>, + body: Bytes, cli: &CliOptions, ) -> Result<String> { + let body = &mut serde_json::Deserializer::from_slice(body.deref()); + let body: PayloadWrapper<CreateItem> = serde_path_to_error::deserialize(body)?; let auth = body.auth; let payload = body.payload; let database_key = auth_to_database_key(auth)?; @@ -69,11 +74,9 @@ pub fn create_item( }) } -pub fn update_item( - owner: String, - init_db: &RwLock<HashSet<String>>, - body: PayloadWrapper<UpdateItem>, -) -> Result<()> { +pub fn update_item(owner: String, init_db: &RwLock<HashSet<String>>, body: Bytes) -> Result<()> { + let body = &mut serde_json::Deserializer::from_slice(body.deref()); + let body: PayloadWrapper<UpdateItem> = serde_path_to_error::deserialize(body)?; let auth = body.auth; let payload = body.payload; let database_key = auth_to_database_key(auth)?; @@ -87,9 +90,11 @@ pub fn update_item( pub fn bulk( owner: String, init_db: &RwLock<HashSet<String>>, - body: PayloadWrapper<Bulk>, + body: Bytes, cli: &CliOptions, ) -> Result<Value> { + let body = &mut serde_json::Deserializer::from_slice(body.deref()); + let body: PayloadWrapper<Bulk> = serde_path_to_error::deserialize(body)?; let auth = body.auth; let payload = body.payload; let database_key = auth_to_database_key(auth)?; @@ -100,11 +105,9 @@ pub fn bulk( }) } -pub fn delete_item( - owner: String, - init_db: &RwLock<HashSet<String>>, - body: PayloadWrapper<String>, -) -> Result<()> { +pub fn delete_item(owner: String, init_db: &RwLock<HashSet<String>>, body: Bytes) -> Result<()> { + let body = &mut serde_json::Deserializer::from_slice(body.deref()); + let body: PayloadWrapper<String> = serde_path_to_error::deserialize(body)?; let auth = body.auth; let payload = body.payload; let database_key = auth_to_database_key(auth)?; @@ -118,8 +121,10 @@ pub fn delete_item( pub fn create_edge( owner: String, init_db: &RwLock<HashSet<String>>, - body: PayloadWrapper<CreateEdge>, + body: Bytes, ) -> Result<String> { + let body = &mut serde_json::Deserializer::from_slice(body.deref()); + let body: PayloadWrapper<CreateEdge> = serde_path_to_error::deserialize(body)?; let auth = body.auth; let payload = body.payload; let database_key = auth_to_database_key(auth)?; @@ -130,8 +135,10 @@ pub fn create_edge( pub fn get_edges( owner: String, init_db: &RwLock<HashSet<String>>, - body: PayloadWrapper<GetEdges>, + body: Bytes, ) -> Result<Vec<Value>> { + let body = &mut serde_json::Deserializer::from_slice(body.deref()); + let body: PayloadWrapper<GetEdges> = serde_path_to_error::deserialize(body)?; let auth = body.auth; let payload = body.payload; let database_key = auth_to_database_key(auth)?; @@ -142,11 +149,9 @@ pub fn get_edges( }) } -pub fn search( - owner: String, - init_db: &RwLock<HashSet<String>>, - body: PayloadWrapper<Search>, -) -> Result<Vec<Value>> { +pub fn search(owner: String, init_db: &RwLock<HashSet<String>>, body: Bytes) -> Result<Vec<Value>> { + let body = &mut serde_json::Deserializer::from_slice(body.deref()); + let body: PayloadWrapper<Search> = serde_path_to_error::deserialize(body)?; let auth = body.auth; let payload = body.payload; let database_key = auth_to_database_key(auth)?; @@ -177,11 +182,9 @@ pub fn upload_file( }) } -pub fn get_file( - owner: String, - init_db: &RwLock<HashSet<String>>, - body: PayloadWrapper<GetFile>, -) -> Result<Vec<u8>> { +pub fn get_file(owner: String, init_db: &RwLock<HashSet<String>>, body: Bytes) -> Result<Vec<u8>> { + let body = &mut serde_json::Deserializer::from_slice(body.deref()); + let body: PayloadWrapper<GetFile> = serde_path_to_error::deserialize(body)?; let auth = body.auth; let payload = body.payload; let database_key = auth_to_database_key(auth)?;