Redirect planning #
Pure HTTP redirect-decision logic.
decideRedirect inspects a response-line Status and Location header and produces a
RedirectOutcome describing whether to stop or follow, plus the full rewrite required by RFC 9110
§15.4 (Redirect 3xx) and RFC 9112 §3.2 (Request Target).
This module never touches IO or Async.
References:
What the caller must do with the body of the original request when following a redirect.
- empty : RedirectBodyAction
Send an empty body on the redirected request. Chosen when the method changes (303 See Other, or 301/302 on
POST) or when the original body cannot be replayed. - replay : RedirectBodyAction
Reset the original body and resend it on the redirected request. Chosen for method-preserving redirects (307/308) when the body is marked replayable.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
The concrete work the caller must perform to follow a redirect.
- origin : URI.Origin
Target origin (scheme, host, port) for the redirected request.
- target : RequestTarget
Rewritten request target put on the wire: origin-form for same-origin redirects, absolute-form for cross-origin redirects, with any
userinfostripped per RFC 9110 §4.2.4. - method : Method
Method to use for the redirected request (possibly downgraded to
GETfor 301/302 onPOSTor for 303). - headers : Headers
Headers for the redirected request after cross-origin and method-change scrubbing.
- bodyAction : RedirectBodyAction
What to do with the original request body.
- isCrossOrigin : Bool
Whether the redirect crosses origin boundaries (different host, port, or scheme). Useful for credential-handling decisions at the call site.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
Result of evaluating whether to follow a redirect.
- done : RedirectOutcome
Response is final. Stop redirecting and return it.
- follow
(plan : RedirectPlan)
: RedirectOutcome
Follow the redirect described by
plan.
Instances For
Decides whether to follow a redirect given the server's response-line status, version, and headers, the pending request, and whether the request body is replayable.
Returns .done when:
- the status is not a 3xx redirection,
- the response is HTTP/1.0 and the status code is not 301 or 302 (the only redirect codes defined by RFC 2616),
- no
Locationheader is present, - the
Locationvalue does not parse as a URI-reference (RFC 9110 §10.2.2), - the target resolves to a non-
http(s)scheme (SSRF guard), or onlySafeRedirectsistrueand the original method is not safe (RFC 9110 §9.2.1: GET, HEAD, OPTIONS, TRACE).
Returns .follow plan otherwise. The caller is expected to drain the redirect response body and,
when plan.bodyAction == .replay, reset the original body before dispatching the rewritten request.
On a cross-origin hop the original Host header is rewritten to the new origin, but only when one
was present; if the original request carried no Host, supplying one for the new origin is the
caller's responsibility.
Notes on specific status codes that always return .done:
- 300 Multiple Choices — may carry a
Locationnaming the server's preferred choice, but RFC 9110 §15.4.1 leaves the selection to the user agent, so we deliberately do not auto-select. - 304 Not Modified — cache revalidation result, not a navigation redirect.
- 305 Use Proxy — deprecated (RFC 9110 §15.4.6); blocked for security.
- 306 — reserved/unused.
Equations
- One or more equations did not get rendered due to their size.