Skip to content

Expose redirect history on responses #122

Description

@ZilvinasKucinskas

Priority: P1

Describe the issue

When redirects are enabled, Wreq::Response#url exposes only the final URL. Callers cannot inspect which statuses and locations were followed, how many hops occurred, or where a cross-origin transition happened.

The underlying Rust response already stores redirect history entries containing the status, previous URI, resolved destination URI, and redirect-response headers. The Ruby binding should expose that existing data as structured Ruby values without inventing fields that the native history does not retain.

Proposed Ruby API

response = client.get("https://example.com/old")

response.url
# => "https://example.com/new"

response.history.each do |hop|
  puts [hop.status, hop.previous_url, hop.url].inspect
end

response.history.map(&:to_h)
# => [
#   {
#     status: 301,
#     previous_url: "https://example.com/old",
#     url: "https://example.com/new",
#     headers: #<Wreq::Headers ...>
#   }
# ]

history should always return an array, empty when no redirects were followed. Each entry can be an immutable Wreq::RedirectHistoryEntry value object with readers and to_h.

Recommended initial fields:

  • status: integer status of the redirect response;
  • previous_url: URI requested before the redirect;
  • url: resolved destination URI retained by Rust wreq; and
  • headers: duplicate-preserving headers of the redirect response.

Avoid storing response bodies. The first API should not promise the raw Location field separately, request-method rewriting, per-hop timings, or other information Rust wreq does not retain in HistoryEntry.

Acceptance criteria

  • Response#history returns an ordered, immutable view of followed redirects.
  • No-redirect responses return an empty array.
  • Relative redirects expose the resolved destination retained upstream.
  • Cross-origin redirects and the final URL are represented correctly through the retained URI fields.
  • Intermediate headers preserve repeated values.
  • History does not retain intermediate body buffers or prevent connection cleanup.
  • Sensitive URL components are redacted from inspect and default serialization.
  • Tests cover no redirect, one hop, multiple hops, relative locations, cross-origin redirects, and redirects disabled.

Relevant public references

Relevant wreq-ruby source

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions