From 3499f430b1e8d332f6e6300005fef74968805dc5 Mon Sep 17 00:00:00 2001 From: midefos Date: Sat, 18 Jan 2025 04:04:07 +0100 Subject: [PATCH] better unauthorized ip, and adding responder --- Cargo.lock | 40 ++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +++ src/lib.rs | 3 ++- src/main.rs | 7 ++----- src/responder.rs | 50 +++++++++++++++++++++++++++++++++++++++++++----- src/server.rs | 15 +++++++-------- 6 files changed, 99 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f57cbf0..39bc048 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -264,6 +264,44 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.135" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "servme" version = "0.1.0" @@ -273,6 +311,8 @@ dependencies = [ "hyper", "hyper-util", "log", + "serde", + "serde_json", "tokio", "tokio-util", ] diff --git a/Cargo.toml b/Cargo.toml index adc0905..cff7fe3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,9 @@ http-body-util = "0.1.2" hyper = { version = "1.5.2", features = ["http1", "server"] } hyper-util = { version = "0.1", features = ["http1", "server", "tokio"] } +serde = {version = "1.0.217", features = ["derive"]} +serde_json = "1.0.135" + log = { version = "0.4.25", features=["kv"]} [lib] diff --git a/src/lib.rs b/src/lib.rs index edef2d3..7168272 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ mod builder; mod config; -mod server; mod responder; +mod server; +pub use responder::Responder; pub use server::Server; diff --git a/src/main.rs b/src/main.rs index 10805d6..6d4add3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use hyper::{ body::{Bytes, Incoming}, Request, Response, }; -use servme::Server; +use servme::{Responder, Server}; use std::convert::Infallible; #[tokio::main] @@ -16,8 +16,5 @@ async fn main() { } async fn handler(req: Request) -> Result>, Infallible> { - Ok(Response::new(Full::new(Bytes::from(format!( - "Hello World! {}", - req.uri() - ))))) + Responder::text(format!("Hello World! {}", req.uri())) } diff --git a/src/responder.rs b/src/responder.rs index a222c5f..cb59202 100644 --- a/src/responder.rs +++ b/src/responder.rs @@ -1,15 +1,55 @@ -use http::Response; +use http::{header::CONTENT_TYPE, response::Builder, Response}; use http_body_util::Full; use hyper::body::Bytes; +use serde::Serialize; use std::convert::Infallible; pub struct Responder; impl Responder { + pub fn not_found() -> Result>, Infallible> { + Self::response_using_builder(Self::create_builder(401), "Not Found".to_string()) + } + pub fn unathorized() -> Result>, Infallible> { - Ok(Response::builder() - .status(401) - .body(Full::new(Bytes::from("Unauthorized"))) - .unwrap()) + Self::response_using_builder(Self::create_builder(401), "Unathorized".to_string()) + } + + pub fn text(response: String) -> Result>, Infallible> { + Self::response_using_builder(Self::create_builder(200), response) + } + + pub fn json(json: T) -> Result>, Infallible> + where + T: Serialize, + { + Self::json_using_status(200, json) + } + + pub fn text_using_status( + status: u16, + response: String, + ) -> Result>, Infallible> { + Self::response_using_builder(Self::create_builder(status), response) + } + + pub fn json_using_status(status: u16, json: T) -> Result>, Infallible> + where + T: Serialize, + { + let builder = Self::create_builder(status).header(CONTENT_TYPE, "application/json"); + + Self::response_using_builder(builder, serde_json::to_string(&json).unwrap()) + } + + fn response_using_builder( + builder: Builder, + response: String, + ) -> Result>, Infallible> { + Ok(builder.body(Full::new(Bytes::from(response))).unwrap()) + } + + fn create_builder(status: u16) -> Builder { + Response::builder().status(status) } } diff --git a/src/server.rs b/src/server.rs index 126c43e..2356e48 100644 --- a/src/server.rs +++ b/src/server.rs @@ -28,8 +28,8 @@ impl Server { .parse() .expect("Invalid IP or port"); let listener = TcpListener::bind(addr).await.unwrap(); - let handler = Arc::new(handler); + let handler = Arc::new(handler); loop { let listener_res = listener.accept().await; if listener_res.is_err() { @@ -37,12 +37,9 @@ impl Server { } let (tcp, client_addr) = listener_res.unwrap(); + let client_ip = client_addr.ip(); let io = TokioIo::new(tcp); - if !self.config.is_ip_authorized(&client_addr.ip()) { - continue; - } - let config = Arc::clone(&self.config); let handler = Arc::clone(&handler); spawn(async move { @@ -55,10 +52,12 @@ impl Server { let handler = Arc::clone(&handler); async move { - if config.is_req_authorized(&req) { - handler(req).await - } else { + if !config.is_ip_authorized(&client_ip) + || !config.is_req_authorized(&req) + { Responder::unathorized() + } else { + handler(req).await } } }),