diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..ed1faa2 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,34 @@ + +pub enum ErrorKind { + InvalidEndpoint, + JsonParseError, +} + +pub struct Error { + kind: ErrorKind, +} + +impl Error { + pub fn new(kind: ErrorKind) -> Error { + Error { + kind, + } + } +} + +impl From for Error { + fn from(_: serde_json::Error) -> Self { + Error { + kind: ErrorKind::JsonParseError, + } + } +} + +impl ToString for Error { + fn to_string(&self) -> String { + match self.kind { + ErrorKind::InvalidEndpoint => "invalid endpoint", + ErrorKind::JsonParseError => "JSON parse error", + }.to_string() + } +} diff --git a/src/http/handler.rs b/src/http/handler.rs index 1deb136..8515d8a 100644 --- a/src/http/handler.rs +++ b/src/http/handler.rs @@ -88,8 +88,6 @@ fn endpoint_handler( res: &mut super::Response, endpoint: &str, ) { - let mut buf = [0; 8192]; - res.add_header("Cache-Control", "no-store"); let mut error = |code: u16, err_str: &str, client: &mut super::HttpStream| { @@ -97,10 +95,21 @@ fn endpoint_handler( res.status(code); res.error_info(err_str.to_string()); + let mut obj = serde_json::Value::Object(serde_json::Map::new()); + obj["status"] = serde_json::Value::String("error".to_string()); + obj["message"] = serde_json::Value::String(err_str.to_string()); + let buf = obj.to_string() + "\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"); + if let Err(e) = res.send(&mut client.stream) { println!("Unable to send: {}", e); client.server_keep_alive = false; } + + client.stream.write_all(buf.as_bytes()); }; let length = req.find_header("Content-Length"); @@ -126,6 +135,7 @@ fn endpoint_handler( } }; + let mut buf = [0; 8192]; client.stream.read_exact(&mut buf[..length]); // TODO decompress @@ -142,7 +152,7 @@ fn endpoint_handler( let buf = match usimp::endpoint(endpoint, input) { Ok(output) => output.to_string() + "\r\n", - Err(e) => format!("{{\"status\":\"error\",\"message\":\"{}\"}}\r\n", e), + Err(e) => return error(500, e.to_string().as_str(), client), }; // TODO compress diff --git a/src/main.rs b/src/main.rs index 1bd8744..9feac3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,17 @@ +use std::net::{SocketAddr, TcpListener, UdpSocket}; +use std::sync::Arc; +use std::sync::Mutex; +use std::thread; + +use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; +use threadpool::ThreadPool; + mod database; mod http; mod udp; mod usimp; mod websocket; - -use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; -use std::net::{SocketAddr, TcpListener, UdpSocket}; -use std::sync::Arc; -use std::sync::Mutex; -use std::thread; -use threadpool::ThreadPool; +mod error; enum SocketType { Http, diff --git a/src/usimp/mod.rs b/src/usimp/mod.rs index 3561b81..867939c 100644 --- a/src/usimp/mod.rs +++ b/src/usimp/mod.rs @@ -1,11 +1,13 @@ -use crate::database; use serde::{Deserialize, Serialize}; use serde_json; -pub fn endpoint(endpoint: &str, input: serde_json::Value) -> serde_json::Result { +use crate::database; +use crate::error::*; + +pub fn endpoint(endpoint: &str, input: serde_json::Value) -> Result { match endpoint { "echo" => Ok(serde_json::to_value(echo(serde_json::from_value(input)?))?), - _ => Ok("{}".into()), + _ => Err(Error::new(ErrorKind::InvalidEndpoint)), } }