From 3ecdb8c1d98750eee1c5c65b28afa5bfebb36ef7 Mon Sep 17 00:00:00 2001 From: Franklin Date: Mon, 29 Aug 2022 12:42:04 -0400 Subject: [PATCH] Added read_body logger --- Cargo.lock | 74 ++++++++++++++++++++++++++++++++++++- Cargo.toml | 6 ++- src/extensions/mod.rs | 3 +- src/extensions/read_body.rs | 69 ++++++++++++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 src/extensions/read_body.rs diff --git a/Cargo.lock b/Cargo.lock index 8e955c2..9486663 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,10 +183,13 @@ dependencies = [ [[package]] name = "actix-web-utils" -version = "0.1.5" +version = "0.1.6" dependencies = [ "actix-web", + "env_logger", + "futures-util", "log", + "pin-project", "serde", "serde_json", ] @@ -232,6 +235,17 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -387,6 +401,19 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "firestorm" version = "0.5.1" @@ -447,6 +474,7 @@ dependencies = [ "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -527,6 +555,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "idna" version = "0.2.3" @@ -712,6 +746,26 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -930,6 +984,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "time" version = "0.3.14" @@ -1084,6 +1147,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 4c994cb..bf47841 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web-utils" -version = "0.1.5" +version = "0.1.6" edition = "2021" authors = ["Franklin E. Blanco"] description = "Just some useful addons for actix web." @@ -13,3 +13,7 @@ actix-web = "4.1.0" serde_json = { version = "1" } serde = { version = "1.0", features = ["derive"] } log = { version = "0.4", features = ["serde"] } + +env_logger = "0.9" +futures-util = { version = "0.3.17", default-features = false, features = ["std"] } +pin-project = "1" \ No newline at end of file diff --git a/src/extensions/mod.rs b/src/extensions/mod.rs index e4d56db..6568268 100644 --- a/src/extensions/mod.rs +++ b/src/extensions/mod.rs @@ -1,2 +1,3 @@ pub mod typed_response; -pub mod logger; \ No newline at end of file +pub mod logger; +pub mod read_body; \ No newline at end of file diff --git a/src/extensions/read_body.rs b/src/extensions/read_body.rs new file mode 100644 index 0000000..aa461e9 --- /dev/null +++ b/src/extensions/read_body.rs @@ -0,0 +1,69 @@ +use std::{ + future::{ready, Ready}, + rc::Rc, +}; + +use actix_web::{ + dev::{self, Service, ServiceRequest, ServiceResponse, Transform}, + web::BytesMut, + Error, HttpMessage, +}; +use futures_util::{future::LocalBoxFuture, stream::StreamExt}; + +/// Pass this struct to App::new().wrap(HERE) to log the request body each time a request is made. Stole it from here: +pub struct Logging; + +impl Transform for Logging +where + S: Service, Error = Error>, + S::Future: 'static, + B: 'static, +{ + type Response = ServiceResponse; + type Error = Error; + type InitError = (); + type Transform = LoggingMiddleware; + type Future = Ready>; + + fn new_transform(&self, service: S) -> Self::Future { + ready(Ok(LoggingMiddleware { + service: Rc::new(service), + })) + } +} + +pub struct LoggingMiddleware { + // This is special: We need this to avoid lifetime issues. + service: Rc, +} + +impl Service for LoggingMiddleware +where + S: Service, Error = Error> + 'static, + S::Future: 'static, + B: 'static, +{ + type Response = ServiceResponse; + type Error = Error; + type Future = LocalBoxFuture<'static, Result>; + + dev::forward_ready!(service); + + fn call(&self, mut req: ServiceRequest) -> Self::Future { + let svc = self.service.clone(); + + Box::pin(async move { + let mut body = BytesMut::new(); + let mut stream = req.take_payload(); + while let Some(chunk) = stream.next().await { + body.extend_from_slice(&chunk?); + } + + println!("request body: {body:?}"); + let res = svc.call(req).await?; + + println!("response: {:?}", res.headers()); + Ok(res) + }) + } +} \ No newline at end of file