Unverified Commit 51519271 authored by Vasili Novikov's avatar Vasili Novikov
Browse files

Improve HTTP body parsing error reporting

parent 212d99aa
Showing with 67 additions and 51 deletions
+67 -51
......@@ -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"
......
......@@ -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"] }
......
......@@ -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!(
......
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)
});
......
......@@ -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)?;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment