-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: request, response and response body hooks
- Loading branch information
Gabriele Musco
committed
Sep 26, 2024
1 parent
d85f44b
commit 1f5e562
Showing
6 changed files
with
152 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//! Hooks to intercept the request, response and response body | ||
use super::{Request, Response}; | ||
|
||
/// Hook that gets called before sending the request, right after it's constructed | ||
pub trait RequestHook: Send + Sync { | ||
/// Intercept the request and return it with or without changes | ||
fn intercept(&self, req: Request) -> Request; | ||
} | ||
|
||
/// Hook that gets called once the request is completed and headers have been received | ||
pub trait ResponseHook: Send + Sync { | ||
/// Intercept the response and return it with or without changes | ||
fn intercept(&self, res: Response) -> Response; | ||
} | ||
|
||
/// Hook that gets called once the request is completed and the full body has been received | ||
pub trait ResponseBodyHook: Send + Sync { | ||
/// Intercept the response body and return it with or without changes | ||
fn intercept(&self, body: String) -> String; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#![cfg(not(target_arch = "wasm32"))] | ||
#![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] | ||
mod support; | ||
|
||
use std::sync::{Arc, Mutex}; | ||
|
||
use support::server; | ||
|
||
use reqwest::{ | ||
hooks::{RequestHook, ResponseBodyHook, ResponseHook}, | ||
Client, | ||
}; | ||
|
||
#[derive(Default)] | ||
struct MyHook { | ||
pub req_visited: Arc<Mutex<bool>>, | ||
pub res_visited: Arc<Mutex<bool>>, | ||
pub body_visited: Arc<Mutex<bool>>, | ||
} | ||
|
||
impl RequestHook for MyHook { | ||
fn intercept(&self, req: reqwest::Request) -> reqwest::Request { | ||
*self.req_visited.lock().unwrap() = true; | ||
req | ||
} | ||
} | ||
|
||
impl ResponseHook for MyHook { | ||
fn intercept(&self, res: reqwest::Response) -> reqwest::Response { | ||
*self.res_visited.lock().unwrap() = true; | ||
res | ||
} | ||
} | ||
|
||
impl ResponseBodyHook for MyHook { | ||
fn intercept(&self, body: String) -> String { | ||
*self.body_visited.lock().unwrap() = true; | ||
body | ||
} | ||
} | ||
|
||
#[tokio::test] | ||
async fn full_hook_chain() { | ||
let _ = env_logger::try_init(); | ||
|
||
let server = server::http(move |_req| async { http::Response::new("Hello".into()) }); | ||
|
||
let hook = Arc::new(MyHook::default()); | ||
|
||
let client = Client::builder() | ||
.request_hook(hook.clone()) | ||
.response_hook(hook.clone()) | ||
.response_body_hook(hook.clone()) | ||
.build() | ||
.unwrap(); | ||
|
||
let res = client | ||
.get(&format!("http://{}/text", server.addr())) | ||
.send() | ||
.await | ||
.expect("Failed to get"); | ||
assert_eq!(res.content_length(), Some(5)); | ||
let text = res.text().await.expect("Failed to get text"); | ||
assert_eq!("Hello", text); | ||
assert!(*hook.req_visited.lock().unwrap()); | ||
assert!(*hook.res_visited.lock().unwrap()); | ||
assert!(*hook.body_visited.lock().unwrap()); | ||
} |