From 04511bd78fb880c096eeeff4541ff142738886e6 Mon Sep 17 00:00:00 2001 From: Mykhailo Chalyi Date: Wed, 15 Apr 2026 08:24:59 -0500 Subject: [PATCH] fix(python): preserve hardened redirect policy --- crates/fetchkit-python/src/lib.rs | 8 ++++---- crates/fetchkit/src/tool.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/crates/fetchkit-python/src/lib.rs b/crates/fetchkit-python/src/lib.rs index b71e06f..d869ff0 100644 --- a/crates/fetchkit-python/src/lib.rs +++ b/crates/fetchkit-python/src/lib.rs @@ -189,7 +189,7 @@ impl PyFetchKitTool { respect_proxy_env=false, allowed_ports=None, blocked_hosts=None, - same_host_redirects_only=false, + same_host_redirects_only=None, hardened=false ))] fn new( @@ -203,7 +203,7 @@ impl PyFetchKitTool { respect_proxy_env: bool, allowed_ports: Option>, blocked_hosts: Option>, - same_host_redirects_only: bool, + same_host_redirects_only: Option, hardened: bool, ) -> PyResult { let mut builder = ToolBuilder::new() @@ -217,7 +217,7 @@ impl PyFetchKitTool { builder = builder .block_private_ips(block_private_ips) - .same_host_redirects_only(same_host_redirects_only); + .same_host_redirects_only_if_set(same_host_redirects_only); if let Some(ua) = user_agent { builder = builder.user_agent(ua); @@ -324,7 +324,7 @@ fn fetch( as_text: Option, ) -> PyResult { let tool = PyFetchKitTool::new( - true, true, None, None, None, None, true, false, None, None, false, false, + true, true, None, None, None, None, true, false, None, None, None, false, )?; tool.fetch(url, method, as_markdown, as_text) } diff --git a/crates/fetchkit/src/tool.rs b/crates/fetchkit/src/tool.rs index 46f9806..76e2b1e 100644 --- a/crates/fetchkit/src/tool.rs +++ b/crates/fetchkit/src/tool.rs @@ -245,6 +245,14 @@ impl ToolBuilder { self } + /// Restrict redirects to the original host only when the caller set a value. + pub fn same_host_redirects_only_if_set(mut self, enable: Option) -> Self { + if let Some(enable) = enable { + self.same_host_redirects_only = enable; + } + self + } + /// Control private/reserved IP range blocking (SSRF prevention) /// /// Enabled by default. When enabled, FetchKit resolves hostnames to IP @@ -1112,6 +1120,26 @@ mod tests { assert!(tool.same_host_redirects_only); } + #[test] + fn test_tool_builder_preserves_hardened_redirect_policy_when_override_is_unset() { + let tool = Tool::builder() + .hardened() + .same_host_redirects_only_if_set(None) + .build(); + + assert!(tool.same_host_redirects_only); + } + + #[test] + fn test_tool_builder_allows_explicit_redirect_policy_override() { + let tool = Tool::builder() + .hardened() + .same_host_redirects_only_if_set(Some(false)) + .build(); + + assert!(!tool.same_host_redirects_only); + } + #[test] fn test_tool_metadata() { let tool = Tool::default();