Skip to content

Support a pluggable redirect strategy in RedirectConfiguration #923

Open

Description

@o-nnerb

Following up on #604: is fine-grained control over redirects (a pluggable strategy, not just .disallow/.follow) still something you'd want upstream?

Security motivation, not just convenience: .follow already strips Authorization/Cookie on cross-origin redirects, but that policy is fixed and all-or-nothing. There's no way for a caller to go further: refuse a redirect to a host outside an allow-list, strip additional headers, or just audit where a request ends up. URLSession gives callers that hook via its per-task delegate; AsyncHTTPClient has none.

Prototyped it in a fork: request-dl#6. A HTTPClientRedirectStrategy protocol (conforming types, not just closures) gets the full per-request history plus the candidate request/response for each redirect, and decides follow/refuse/throw. Aims at the "pluggable redirect strategies" + "pass data around" gap from this comment: #604 (comment)

Happy to open this as a real PR against main if there's still interest, or adjust the design first.

Activity

  1. o-nnerb commented on Sep 5, 2026

    @o-nnerb
    ContributorAuthor

    Extended the prototype since opening this: the strategy now also works over the delegate-based execute(request:delegate:...) API, not just the Concurrency one. Same HTTPClientRedirectStrategy/HTTPClientRedirectContext types, so callers building on the older API (streaming through a custom HTTPClientResponseDelegate) get the same hook. RedirectHandler bridges between the two APIs' request/body types internally, and .doNotFollow works the same way on both now too.

    Draft PR against main, with tests for both APIs: request-dl#9

    Still happy to adjust the design if there's a different shape you'd want before this goes up as a real PR here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions