ADR-016: Automatic HTTP Redirect Handling¶
Estado: Accepted Date: 2026-02-11 Deciders: Rodrigo Roldan
Context¶
HTTP clients must decide how to handle redirect responses (3xx status codes). Key questions:
Should redirects be followed automatically or require manual handling?
How should the HTTP method change across redirects?
How to prevent infinite redirect loops?
Relevant RFCs:
RFC 7231 (HTTP/1.1 Semantics): Defines redirect status codes
RFC 7538: 308 Permanent Redirect
Decision¶
Automatic redirect following is enabled by default with configurable behavior.
Parameters:
allow_redirects: bool = True— Enable/disable automatic followingmax_redirects: int = 30— Maximum number of redirects before raisingTooManyRedirects
Method conversion rules:
Status Code |
Behavior |
|---|---|
301 Moved Permanently |
POST/PUT/PATCH -> GET (drop body). HEAD preserved. |
302 Found |
POST/PUT/PATCH -> GET (drop body). HEAD preserved. |
303 See Other |
Always convert to GET (drop body). |
307 Temporary Redirect |
Preserve original method and body. |
308 Permanent Redirect |
Preserve original method and body. |
Security behavior:
Authorizationheader is stripped when the redirect changes the hostRedirect history is tracked in
response.history
Cycle detection:
A
visited_urlsset tracks all URLs visited during a redirect chainIf a URL is visited twice,
RedirectLoopErroris raised immediatelyThis catches cycles (A -> B -> A) before reaching
max_redirects
Consequences¶
Positive¶
Ergonomic: Users get final responses without manual redirect handling
Safe: Method conversion prevents unintended POST replays
Secure: Auth header stripping prevents credential leakage to third parties
Predictable: Cycle detection provides fast failure on redirect loops
Negative¶
Implicit behavior: Redirects happen silently, may surprise users
Performance: Each redirect adds a round-trip
Mitigations¶
allow_redirects=Falsefor users who want manual controlResponse history accessible for debugging redirect chains
max_redirectsprevents runaway chains
Alternatives Considered¶
Manual redirects only: Rejected. Poor DX, every client would need redirect logic.
Always preserve method: Rejected. Violates RFC 7231 and causes unintended POST replays.
No cycle detection: Rejected.
max_redirectsalone is too slow for tight loops.
References¶
RFC 7231 Section 6.4 (Redirection)
RFC 7538 (308 Permanent Redirect)
Python requests library redirect behavior
httpx redirect implementation