Skip to content

feat(ext/node): support DENO_SERVE_ADDRESS override in node:http servers#34662

Merged
bartlomieju merged 1 commit into
mainfrom
feat/node-http-address-override
Jun 1, 2026
Merged

feat(ext/node): support DENO_SERVE_ADDRESS override in node:http servers#34662
bartlomieju merged 1 commit into
mainfrom
feat/node-http-address-override

Conversation

@bartlomieju

Copy link
Copy Markdown
Member

The top-level Deno.serve() already honors the process-wide
DENO_SERVE_ADDRESS override, but node:http servers ignored it, so an
application using the Node compatibility layer could not be transparently
rebound to a unix/vsock/tunnel control plane the way native Deno servers
can. This matters for environments like Deno Deploy and the desktop
runtime where the serve address is injected via the environment.

This adds a listen() override on http.Server and https.Server that
consumes the same override the first time a server binds. TCP overrides
rewrite the listen address in place. For unix/vsock/tunnel overrides the
server either listens on the override address only (default) or on both
the app-supplied address and the override (duplicate). Non-TCP override
connections are wrapped in a lightweight Duplex around Deno.Conn and fed
into the normal connection listener, so the llhttp parser and the rest of
the node:http pipeline handle them exactly like a native TCP connection.

Add a `listen()` override on `http.Server` (and `https.Server`) that
honors the process-wide serve address override (DENO_SERVE_ADDRESS) so
node:http servers behave like the top-level Deno.serve():

* Without `duplicate`: the first server to call `listen()` consumes the
  override. For TCP overrides the listen() args are rewritten in place.
  For unix/vsock/tunnel overrides the app-supplied TCP listen is skipped
  and a Deno listener is opened on the override address only.
* With `duplicate`: the app-supplied address is used AND an additional
  override listener is started in parallel, regardless of transport.

Non-TCP override listeners accept Deno.Conn connections and feed them to
the HTTP server's normal connection listener via a lightweight Duplex
wrapper, so the llhttp parser and the rest of the node:http pipeline
handle the request the same way they would for a native TCP connection.

Adds specs covering TCP override, TCP duplicate, unix duplicate, unix
override-only, and https duplicate paths.
@bartlomieju
bartlomieju merged commit 7ab8ca9 into main Jun 1, 2026
268 of 270 checks passed
@bartlomieju
bartlomieju deleted the feat/node-http-address-override branch June 1, 2026 12:53
bartlomieju added a commit that referenced this pull request Jun 5, 2026
…rving (#34949)

Upstream PR #34662 landed the `DENO_SERVE_ADDRESS` override for
`node:http`/`node:https`, and PR #34676 wired `Deno.serve()` to call
`op_http_notify_serving()` so that `DENO_AUTO_SERVE` setups can wait for
a "Serving" event over `DENO_UNSTABLE_CONTROL_SOCK`. Node servers were
left out: they observed the override address but never fired the notification, so
a control plane waiting on the socket would hang.

This hooks `notifyAddressOverrideServing()` into the `listen()` path of
both `http.Server` and `https.Server` (and into `startOverrideListener` for
non-TCP override transports) so `node:http` servers fire the same notification
that `Deno.serve()` does. The unconfigured spec gains a `node:http` variant
exercising the full `DENO_AUTO_SERVE` +
`DENO_SERVE_ADDRESS=duplicate,unix:...` + `DENO_UNSTABLE_CONTROL_SOCK`
flow.

Co-authored-by: Avocet <[email protected]>
littledivy pushed a commit to crowlKats/deno that referenced this pull request Jun 10, 2026
…ers (denoland#34662)

The top-level `Deno.serve()` already honors the process-wide
`DENO_SERVE_ADDRESS` override, but node:http servers ignored it, so an
application using the Node compatibility layer could not be
transparently rebound to a unix/vsock/tunnel control plane the way native Deno servers
can. This matters for environments like Deno Deploy and the desktop
runtime where the serve address is injected via the environment.

This adds a `listen()` override on `http.Server` and `https.Server` that
consumes the same override the first time a server binds. TCP overrides
rewrite the listen address in place. For unix/vsock/tunnel overrides the
server either listens on the override address only (default) or on both
the app-supplied address and the override (`duplicate`). Non-TCP
override connections are wrapped in a lightweight Duplex around `Deno.Conn` and
fed into the normal connection listener, so the llhttp parser and the rest
of the node:http pipeline handle them exactly like a native TCP connection.
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.

1 participant