diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b40168..ca980d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Added +## [0.4.0] - 2026-06-12 -- Pluggable HTTP transport abstraction (`HttpTransport`, `TransportRequest`, `TransportResponse`, `TransportError`, `ReqwestTransport`). A host application can route fetchkit's outbound HTTP through its own egress boundary via `FetchOptions::transport`, while fetchkit retains URL validation, DNS policy (resolve-then-check, pinned addrs), manual redirect following, bot-auth signing, and body-size/timeout caps. Default behavior is unchanged (`ReqwestTransport`). +### Highlights + +- Pluggable HTTP transport: host applications can route all of fetchkit's outbound HTTP through their own egress boundary via `FetchOptions::transport` or `ToolBuilder::transport`, while fetchkit retains URL validation, DNS policy (resolve-then-check with pinned addresses), manual redirect following, bot-auth signing, and body-size/timeout caps. Default behavior is unchanged (`ReqwestTransport`). +- Policy hardening alongside the transport refactor: YouTube and HackerNews API hosts are now DNS-pinned, Wikipedia/package-registry/arXiv/HackerNews redirects are validated per hop instead of delegated to reqwest, and specialized-fetcher JSON reads are capped at `max_body_size`. +- Local file saver symlink handling hardened. + +### Breaking Changes + +- `FetchOptions` gained a public `transport` field. Code constructing `FetchOptions` with an exhaustive struct literal must add the field or switch to `..Default::default()`. No behavior change when `transport` is `None`. +- `FetchOptions`, `Tool`, and `ToolBuilder` now have manual `Debug` impls (the transport renders as `""` or `"None"`); derived-`Debug` output formats changed accordingly. + +### What's Changed + +* feat(transport): pluggable HttpTransport abstraction ([#135](https://github.com/everruns/fetchkit/pull/135)) +* fix(fetchkit): harden local file saver symlink handling ([f857737](https://github.com/everruns/fetchkit/commit/f857737)) + +**Full Changelog**: https://github.com/everruns/fetchkit/compare/v0.3.0...v0.4.0 ## [0.3.0] - 2026-05-18 @@ -198,7 +214,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 **Full Changelog**: https://github.com/everruns/fetchkit/commits/v0.1.0 -[Unreleased]: https://github.com/everruns/fetchkit/compare/v0.3.0...HEAD +[Unreleased]: https://github.com/everruns/fetchkit/compare/v0.4.0...HEAD +[0.4.0]: https://github.com/everruns/fetchkit/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/everruns/fetchkit/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/everruns/fetchkit/compare/v0.1.3...v0.2.0 [0.1.3]: https://github.com/everruns/fetchkit/compare/v0.1.2...v0.1.3 diff --git a/Cargo.lock b/Cargo.lock index 401ff38..fb294df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -577,7 +577,7 @@ checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fetchkit" -version = "0.3.0" +version = "0.4.0" dependencies = [ "async-trait", "base64", @@ -604,7 +604,7 @@ dependencies = [ [[package]] name = "fetchkit-cli" -version = "0.3.0" +version = "0.4.0" dependencies = [ "clap", "fetchkit", @@ -615,7 +615,7 @@ dependencies = [ [[package]] name = "fetchkit-python" -version = "0.3.0" +version = "0.4.0" dependencies = [ "fetchkit", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index eacdf71..ded38b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = ["crates/*"] [workspace.package] -version = "0.3.0" +version = "0.4.0" edition = "2021" license = "MIT" authors = ["Everruns"] diff --git a/crates/fetchkit-cli/Cargo.toml b/crates/fetchkit-cli/Cargo.toml index a53708d..0fc63f5 100644 --- a/crates/fetchkit-cli/Cargo.toml +++ b/crates/fetchkit-cli/Cargo.toml @@ -21,7 +21,7 @@ default = [] bot-auth = ["fetchkit/bot-auth"] [dependencies] -fetchkit = { path = "../fetchkit", version = "0.3.0" } +fetchkit = { path = "../fetchkit", version = "0.4.0" } tokio = { workspace = true } clap = { workspace = true } serde = { workspace = true }