Skip to content

v0.5.0

Latest

Choose a tag to compare

@antrixy antrixy released this 24 Sep 14:09
· 2 commits to main since this release
8d643fb

The request reqtrail sends is now the request it built. 0.4.1's transport re-read the URL it had just shown you and rebuilt what to send from that text, and two things were lost on the way. 0.5.0 builds the endpoint and target once, in the core, and the transport sends them without parsing anything.

Every example below is captured output from the 0.5.0 binary; the wire lines are what a raw receiver captured.

A bare ? is sent as shown

$ reqtrail run bare.json
GET http://127.0.0.1:PORT/health?
Host: 127.0.0.1:PORT  (derived)

200

The receiver's request line, 0.4.1 then 0.5.0:

GET /health HTTP/1.1
GET /health? HTTP/1.1

IPv6 literals can be sent

$ reqtrail resolve ipv6.json
GET http://[::1]:8080/health?
Host: [::1]:8080  (derived)

0.4.1 resolved this correctly and then failed ENOTFOUND: it handed [::1] — brackets included — to Node as a hostname. 0.5.0 connects to ::1.

HTTPS to an IPv6 literal fails on some Node versions, and reqtrail does not work around it. Node's security releases for CVE-2026-48618 stopped matching IPv6 addresses against a certificate's IP entries (nodejs/node#64144), so a correctly certified https://[::1]/… fails with ERR_TLS_CERT_ALTNAME_INVALID, exit 3. Measured on Node 22.23.2; Node 24.4.1 verifies it; fixed upstream in Node 26.6.0. The failure is closed, and reqtrail does not check certificates itself.

Newly refused: framing headers, and most Connection values

reqtrail sends GET without a body. A workspace that sets Content-Length, Transfer-Encoding, Expect, Upgrade or Trailer is now refused, whatever the value:

$ reqtrail run framing.json
reqtrail: headers[0]: a workspace may not set "Transfer-Encoding"; reqtrail sends GET without a body and does not model message framing, so this header would change what is sent in a way the request shown would not [header.framing]

On 0.4.1 each of these changed what went out, or made the send wait, in a way the shown request did not: Transfer-Encoding: chunked made Node write a body, 0\r\n\r\n, that nothing displayed; Content-Length: 5 left a real server waiting for five bytes forever; Upgrade answered with 101 never returned; Trailer exited 3, "send attempted", when nothing had been attempted — it is now exit 1.

Connection may appear once, as close or keep-alive. Anything else is refused, and the refusal does not show the value, which may be a secret:

$ reqtrail run conn.json
reqtrail: headers[0]: Connection may appear once, with the value close or keep-alive; reqtrail does not model other connection options, so it does not send them. The value is not shown [header.connection]

This is why 0.5.0 is not a patch release. Some of these refusals remove false output; others refuse a header that 0.4.1 sent as written — Expect: 100-continue, Connection: Upgrade. If a workspace of yours sets one, remove it. TE, Keep-Alive and Proxy-Connection are not refused.

Evidence

Pre-registered before the change: EXACT-TRANSPORT-PREREGISTRATION.md. What happened, including four predictions that were wrong and a Node regression found along the way: EXACT-TRANSPORT-EVIDENCE.md.