From ab40248d489b01a793eb2d6dc8a6c7186b1f7de6 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Tue, 18 May 2021 19:24:33 +0200 Subject: [PATCH] Using serde_json --- Cargo.toml | 3 ++- src/http/handler.rs | 40 +++++++++++++--------------------------- src/main.rs | 6 +----- src/usimp/mod.rs | 41 +++++++++++++++++++++-------------------- 4 files changed, 37 insertions(+), 53 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f6ffd1e..abcf0a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,8 @@ edition = "2018" [dependencies] threadpool = "1.0" -json = "0.12.4" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.64" openssl = {version = "0.10", features = ["vendored"]} chrono = "0.4" flate2 = "1.0.0" diff --git a/src/http/handler.rs b/src/http/handler.rs index 61739de..1c0a4fd 100644 --- a/src/http/handler.rs +++ b/src/http/handler.rs @@ -1,10 +1,7 @@ use super::Method; use crate::usimp; use crate::websocket; -use chrono; -use json; -use std::borrow::Borrow; -use std::sync::{Arc, Mutex}; +use serde_json; pub struct HttpStream { pub stream: super::Stream, @@ -53,17 +50,12 @@ fn request_handler(client: &mut super::HttpStream) { let parts: Vec<&str> = req.uri.split('/').collect(); match parts[2..] { ["entity", entity] => res.status(501), - [endpoint] => match usimp::is_valid_endpoint(endpoint) { - true => match req.method { - Method::POST => { - return endpoint_handler(client, &req, &mut res, endpoint) - } - _ => { - res.status(405); - res.add_header("Allow", "POST"); - } - }, - false => res.status(400), + [endpoint] => match req.method { + Method::POST => return endpoint_handler(client, &req, &mut res, endpoint), + _ => { + res.status(405); + res.add_header("Allow", "POST"); + } }, _ => res.status(400), } @@ -137,16 +129,7 @@ fn endpoint_handler( client.stream.read_exact(&mut buf[..length]); // TODO decompress - let input = match json::parse(match std::str::from_utf8(&buf[..length]) { - Ok(source) => source, - Err(e) => { - return error( - 400, - format!("Unable to parse payload: {}", &e).as_str(), - client, - ) - } - }) { + let input = match serde_json::from_slice(&buf[..length]) { Ok(val) => val, Err(e) => { return error( @@ -156,10 +139,13 @@ fn endpoint_handler( ) } }; - let output = usimp::endpoint(endpoint, input); + + let buf = match usimp::endpoint(endpoint, input) { + Ok(output) => output.to_string() + "\r\n", + Err(e) => "{\"status\":\"error\"}\r\n".to_string(), + }; // TODO compress - let buf = json::stringify(output) + "\r\n"; let length = buf.as_bytes().len(); res.add_header("Content-Length", length.to_string().as_str()); res.add_header("Content-Type", "application/json; charset=utf-8"); diff --git a/src/main.rs b/src/main.rs index e52e0bf..1bd8744 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,12 +4,8 @@ mod udp; mod usimp; mod websocket; -use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod, SslStream}; -use r2d2; -use r2d2::{ManageConnection, Pool}; -use r2d2_postgres::{postgres::NoTls, PostgresConnectionManager}; +use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; use std::net::{SocketAddr, TcpListener, UdpSocket}; -use std::ops::Deref; use std::sync::Arc; use std::sync::Mutex; use std::thread; diff --git a/src/usimp/mod.rs b/src/usimp/mod.rs index acb1e7e..3561b81 100644 --- a/src/usimp/mod.rs +++ b/src/usimp/mod.rs @@ -1,35 +1,36 @@ use crate::database; -use json; +use serde::{Deserialize, Serialize}; +use serde_json; -static ENDPOINTS: [(&str, fn(json::JsonValue) -> json::JsonValue); 1] = [("echo", echo)]; - -pub fn is_valid_endpoint(endpoint: &str) -> bool { - for (name, _func) in &ENDPOINTS { - if endpoint.eq(*name) { - return true; - } +pub fn endpoint(endpoint: &str, input: serde_json::Value) -> serde_json::Result { + match endpoint { + "echo" => Ok(serde_json::to_value(echo(serde_json::from_value(input)?))?), + _ => Ok("{}".into()), } - false } -pub fn endpoint(endpoint: &str, input: json::JsonValue) -> json::JsonValue { - for (name, func) in &ENDPOINTS { - if endpoint.eq(*name) { - return func(input); - } - } - panic!("invalid endpoint, check with is_valid_endpoint") +#[derive(Serialize, Deserialize)] +pub struct EchoInput { + message: String, } -pub fn echo(input: json::JsonValue) -> json::JsonValue { +#[derive(Serialize, Deserialize)] +pub struct EchoOutput { + message: String, + database: Option, +} + +pub fn echo(input: EchoInput) -> EchoOutput { let backend = database::client(); - let mut output = input.clone(); + let mut output = EchoOutput { + message: input.message, + database: None, + }; match backend { database::Client::Postgres(mut client) => { let res = client.query("SELECT * FROM test", &[]).unwrap(); for row in res { - let val: i32 = row.get(0); - output["database"] = val.into(); + output.database = Some(row.get(0)); } } }