|
| 1 | +#![feature(async_await)] |
| 2 | + |
| 3 | +use futures::future::BoxFuture; |
| 4 | +use futures::io::AsyncReadExt; |
| 5 | +use surf::middleware::{Body, HttpClient, Middleware, Next, Request, Response}; |
| 6 | + |
| 7 | +struct Doubler; |
| 8 | + |
| 9 | +impl<C: HttpClient> Middleware<C> for Doubler { |
| 10 | + fn handle<'a>( |
| 11 | + &'a self, |
| 12 | + req: Request, |
| 13 | + client: C, |
| 14 | + next: Next<'a, C>, |
| 15 | + ) -> BoxFuture<'a, Result<Response, surf::Exception>> { |
| 16 | + if req.method().is_safe() { |
| 17 | + let mut new_req = Request::new(Body::empty()); |
| 18 | + *new_req.method_mut() = req.method().clone(); |
| 19 | + *new_req.uri_mut() = req.uri().clone(); |
| 20 | + *new_req.version_mut() = req.version().clone(); |
| 21 | + *new_req.headers_mut() = req.headers().clone(); |
| 22 | + Box::pin(async move { |
| 23 | + let mut buf = Vec::new(); |
| 24 | + let (res1, res2) = |
| 25 | + futures::future::join(next.run(req, client.clone()), next.run(new_req, client)) |
| 26 | + .await; |
| 27 | + |
| 28 | + let res = res1?; |
| 29 | + let mut body = res.into_body(); |
| 30 | + body.read_to_end(&mut buf).await?; |
| 31 | + |
| 32 | + let mut res = res2?; |
| 33 | + let mut body = std::mem::replace(res.body_mut(), Body::empty()); |
| 34 | + body.read_to_end(&mut buf).await?; |
| 35 | + |
| 36 | + *res.body_mut() = Body::from(buf); |
| 37 | + Ok(res) |
| 38 | + }) |
| 39 | + } else { |
| 40 | + next.run(req, client) |
| 41 | + } |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +#[runtime::main] |
| 46 | +async fn main() -> Result<(), surf::Exception> { |
| 47 | + femme::start(log::LevelFilter::Info)?; |
| 48 | + let mut res = surf::get("https://httpbin.org/get") |
| 49 | + .middleware(Doubler {}) |
| 50 | + .await?; |
| 51 | + dbg!(&res); |
| 52 | + let body = res.body_bytes().await?; |
| 53 | + let body = String::from_utf8_lossy(&body); |
| 54 | + println!("{}", body); |
| 55 | + Ok(()) |
| 56 | +} |
0 commit comments