Skip to content

fix: expose Headers iterable prototype - #11051

Closed
proggeramlug wants to merge 2 commits into
PerryTS:mainfrom
proggeramlug:fix/10744-axios-response-headers
Closed

proggeramlug wants to merge 2 commits into
PerryTS:mainfrom
proggeramlug:fix/10744-axios-response-headers

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Closes #10744.

What changed

  • resolve handle-backed Fetch values to their intrinsic prototypes in Object.getPrototypeOf
  • expose Headers.prototype[Symbol.iterator] as the same function as Headers.prototype.entries
  • add a package-independent regression covering the prototype identity, own iterator member, iterator alias, and iteration result

Why

Axios's fetch adapter passes the response's Web Headers object to AxiosHeaders.from. Axios deliberately treats a value as safely iterable only when Symbol.iterator is owned somewhere below Object.prototype.

Perry's Headers handle implemented entries() and direct iteration through native dispatch, but Object.getPrototypeOf(headers) returned null and the reflected prototype had no own iterator symbol. Axios therefore classified the value as a plain record, called Object.keys(headers), and copied zero headers.

Verification

  • cargo fmt --all -- --check
  • scripts/check_file_size.sh
  • git diff --check
  • coherent perry + runtime + stdlib build under the perry-dev profile
  • RUST_TEST_THREADS=1 cargo test --profile perry-dev -p perry --test issue_10744_headers_prototype --test issue_any_typed_collection_handle_iterator --test issue_8968_response_headers -- --nocapture
  • real-source axios@1.18.0 against a local HTTP server: Perry now matches Node for the six response header names and returns application/json / works for the two asserted values

Summary by CodeRabbit

  • Bug Fixes
    • Axios responses now preserve headers when using the fetch adapter.
    • Headers objects now expose the expected iterable behavior, including access to entries through their iterator. This improves compatibility with code that inspects Headers prototypes or converts headers into iterable collections.

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: e44d25c0-af28-4135-9681-dbf43a27da29

📥 Commits

Reviewing files that changed from the base of the PR and between f5cfbff and 446c540.

📒 Files selected for processing (4)
  • changelog.d/11051-axios-response-headers.md
  • crates/perry-runtime/src/object/global_this/proto_methods.rs
  • crates/perry-runtime/src/object/object_ops/prototype.rs
  • crates/perry/tests/issue_10744_headers_prototype.rs

Included review availability: Your plan provides up to 8 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

The runtime now resolves WHATWG fetch handles to built-in prototypes and installs Headers.prototype.entries as its own Symbol.iterator. A regression test checks prototype identity and header iteration. The changelog records Axios response-header preservation.

Changes

Headers Prototype Iteration

Layer / File(s) Summary
Fetch handle prototype resolution
crates/perry-runtime/src/object/object_ops/prototype.rs
get_prototype_of_resolved maps recognized fetch handle kinds to available built-in prototypes and retains the existing fallback.
Headers iterator installation and regression test
crates/perry-runtime/src/object/global_this/proto_methods.rs, crates/perry/tests/issue_10744_headers_prototype.rs, changelog.d/11051-axios-response-headers.md
The iterator-symbol helper is renamed, and Headers installs entries as its own [Symbol.iterator]. The regression test checks prototype identity and iteration. The changelog records the Axios header fix.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 446c5

The change adds the intended Headers prototype and iterator behavior with regression coverage; no merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The Object.getPrototypeOf change also adds intrinsic prototype resolution for Response, Request, Blob, File, and FormData. Issue #10744 concerns Axios response headers and requires the `He… Remove the unrelated Response, Request, Blob, File, and FormData prototype mappings, or link requirements that justify those behavior changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: exposing the Headers iterable prototype.
Description check ✅ Passed The description explains the change, its cause, the related issue, and verification results. It omits the template’s Checklist and Screenshots sections, but the required information is mostly complete…
Linked Issues check ✅ Passed [#10744] The change makes Object.getPrototypeOf return Headers.prototype for handle-backed Headers, installs an own Symbol.iterator that aliases entries, and adds a regression test for proto…
Full details: Out of Scope Changes check

Explanation

The Object.getPrototypeOf change also adds intrinsic prototype resolution for Response, Request, Blob, File, and FormData. Issue #10744 concerns Axios response headers and requires the Headers prototype and iterator behavior. The supplied evidence does not connect the other five type mappings to that issue.

Full details: Docstring Coverage

Explanation

Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Landed on main in merge train 259 (#11079), released as v0.5.1642 at 7f4417b5a1.

Your commits are on main — cherry-picked from this PR's head 446c5405b7 and validated as one tree, CI 22/22 green including all 6 gap-suite shards. GitHub cannot auto-close a PR whose commits land under new SHAs via a train rebase, which is why I'm closing this by hand rather than it happening on merge.

Nothing is lost and nothing is needed from you. Thanks.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

axios response.headers is an empty object (status and data correct); node:http's own res.headers works, so the gap is in axios's header assembly

1 participant