From 6d8186bcd4c2018e92392fbf795fe77b74d046a8 Mon Sep 17 00:00:00 2001 From: "Stephen M. Coakley" Date: Tue, 10 Nov 2020 19:49:56 -0600 Subject: [PATCH] Fix client-wide redirect policy not respected (#251) Fix a regression from #240 that caused redirect policies to be ignored if being set client-wide instead of per-request. Fixes #250. --- .github/workflows/ci.yml | 1 + src/client.rs | 9 ++++++++- tests/redirects.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 00573020..67479b48 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,7 @@ jobs: - name: Generate code coverage report uses: actions-rs/tarpaulin@v0.1 with: + version: '0.16.0' args: "-p isahc --run-types Doctests Tests --features cookies,psl" - name: Upload coverage to Codecov diff --git a/src/client.rs b/src/client.rs index 94ba0ef9..7c14eae3 100644 --- a/src/client.rs +++ b/src/client.rs @@ -892,13 +892,20 @@ impl HttpClient { } /// Actually send the request. All the public methods go through here. - async fn send_async_inner(&self, request: Request) -> Result, Error> { + async fn send_async_inner(&self, mut request: Request) -> Result, Error> { let span = tracing::debug_span!( "send_async", method = ?request.method(), uri = ?request.uri(), ); + // Set redirect policy if not specified. + if request.extensions().get::().is_none() { + if let Some(policy) = self.inner.defaults.get::().cloned() { + request.extensions_mut().insert(policy); + } + } + let ctx = interceptor::Context { invoker: Arc::new(self), interceptors: &self.inner.interceptors, diff --git a/tests/redirects.rs b/tests/redirects.rs index da7c6ab3..1af83aae 100644 --- a/tests/redirects.rs +++ b/tests/redirects.rs @@ -144,6 +144,33 @@ fn redirect_also_sends_post(status: u16) { assert_eq!(m2.request().method, "POST"); } +// Issue #250 +#[test] +fn redirect_policy_from_client() { + let m2 = mock!(); + let location = m2.url(); + + let m1 = mock! { + status: 302, + headers { + "Location": location, + } + }; + + let client = HttpClient::builder() + .redirect_policy(RedirectPolicy::Limit(8)) + .build() + .unwrap(); + + let response = client.post(m1.url(), ()).unwrap(); + + assert_eq!(response.status(), 200); + assert_eq!(response.effective_uri().unwrap().to_string(), m2.url()); + + assert_eq!(m1.request().method, "POST"); + assert_eq!(m2.request().method, "GET"); +} + #[test] fn redirect_non_rewindable_body_returns_error() { let m2 = mock!();