Skip to content

node:url: match urlToHttpOptions fields and validation #2976

@andrewtdiz

Description

@andrewtdiz

Summary

Perry's url.urlToHttpOptions() returns a narrow object with protocol, hostname, port, path, and auth. Node returns a fuller HTTP-options object: it includes hash, search, pathname, path, href, optional numeric port, decoded auth, and enumerable own properties from the URL object. Node also rejects non-object inputs with ERR_INVALID_ARG_TYPE, while Perry currently returns an empty object for non-object values.

Node.js behavior

Observed with Node v25.9.0:

const { urlToHttpOptions } = require("node:url");

const u = new URL("https://u%20ser:p%40w@example.com:8080/p/a?q=1#frag");
u.extra = "own";
console.log(Object.keys(urlToHttpOptions(u)));
console.log(urlToHttpOptions(u));

console.log(urlToHttpOptions(new URL("https://example.com")));
urlToHttpOptions("https://example.com/p");

Node outputs keys like:

["extra","protocol","hostname","hash","search","pathname","path","href","port","auth"]
{ extra: "own", protocol: "https:", hostname: "example.com", hash: "#frag", search: "?q=1", pathname: "/p/a", path: "/p/a?q=1", href: "https://u%20ser:p%40w@example.com:8080/p/a?q=1#frag", port: 8080, auth: "u ser:p@w" }
{ protocol: "https:", hostname: "example.com", hash: "", search: "", pathname: "/", path: "/", href: "https://example.com/" }
TypeError ERR_INVALID_ARG_TYPE for a string input

Current Perry behavior

  • crates/perry-runtime/src/url/node_compat.rs::js_url_to_http_options() returns only five properties: protocol, hostname, port, path, and auth.
  • It does not include hash, search, pathname, or href.
  • It does not copy enumerable own properties from the URL object before adding URL-derived options.
  • It formats auth from the stored username / password strings without Node's percent-decoding behavior for userinfo.
  • If object_from_f64(url_f64) fails, it allocates and returns an empty object instead of throwing TypeError ERR_INVALID_ARG_TYPE.

The existing parity fixtures test-parity/node-suite/url/module/url-to-http-options.ts and url-to-http-options-defaults.ts cover only the narrow subset Perry currently returns, so this wider Node behavior can regress silently.

Suggested test surface

  • Assert that urlToHttpOptions(new URL("https://u%20ser:p%40w@example.com:8080/p/a?q=1#frag")) includes hash, search, pathname, path, href, numeric port, and decoded auth === "u ser:p@w".
  • Assert that a URL with no explicit port/auth omits those properties while still including empty hash/search, pathname, path, and href.
  • Assert that enumerable own URL properties are copied to the returned object.
  • Assert that non-object input throws TypeError with code ERR_INVALID_ARG_TYPE.

Scope / non-goals

This issue is scoped to node:url.urlToHttpOptions() result shape, auth decoding, property copying, and input validation. It does not require changing HTTP client option consumption or legacy url.parse().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions