Skip to content

fix(https): certless createServer() listens; _http_server.kConnectionsCheckingInterval (#4974)#4991

Merged
proggeramlug merged 1 commit into
mainfrom
fix/https-async-dispose-4974
Jun 11, 2026
Merged

fix(https): certless createServer() listens; _http_server.kConnectionsCheckingInterval (#4974)#4991
proggeramlug merged 1 commit into
mainfrom
fix/https-async-dispose-4974

Conversation

@proggeramlug

Copy link
Copy Markdown
Contributor

Fixes #4974.

Root cause

test-https-server-async-dispose calls https.createServer() with no options at all — no key, no cert. Node constructs such a server and listen() succeeds (the missing credentials only surface per-connection, as a TLS alert during the handshake). Perry stored tls_config: None and listen() bailed with [node:https] tls config unavailable; refusing to listen before queueing the deferred 'listening' emit — so the listen callback never fired and the test hung. Async-dispose was a red herring; the options were never "torn down", they were never there.

The test additionally asserts server[kConnectionsCheckingInterval]._destroyed via require('_http_server'), which Perry didn't export.

Fix

  • tls.rs: new build_certless_server_config() — a rustls ServerConfig with an always-None cert resolver. The server binds, listens, and accepts TCP; each TLS handshake aborts with a fatal alert (Node-equivalent failure mode).
  • https_server.rs: the no-PEM-material path (has_pem_material() == false) now registers the certless config instead of tls_config: None. Supplied-but-unparseable key/cert keeps the existing refuse-to-listen behavior.
  • kConnectionsCheckingInterval: exported from the http module arm (_http_server aliases to http in cjs_wrap) as a sentinel string key, plus an api-manifest entry so the static property read isn't compile-time-lowered to undefined. server[k] resolves through the ext-http server handle dispatch to a minimal { _destroyed } Timeout shape; the flag lives on HttpServer and is set by all three close paths (http / https / http2).
  • Docs (perry.d.ts, reference.md) regenerated via scripts/regen_api_docs.sh.

Verification

All compiled with this branch's perry + auto-optimized ext crates, against the Node v22 corpus tests staged with the test-compat/node-core/shim common:

test before after
test-https-server-async-dispose hang (timeout), "tls config unavailable" exit 0, all mustCalls fire
test-http-server-async-dispose exit 0
test-http2-server-async-dispose exit 0
with-key/cert https server + https.get round-trip (regression) body: ok, exit 0

Behavior cross-checked against node v26 (certless server listens, disposes, _destroyed === true).

cargo test -p perry-ext-http-server -p perry-api-manifest green (23 + 36), cargo fmt --check clean, file-size gate OK.

No version bump / changelog — maintainer folds metadata at merge.

…sCheckingInterval (#4974)

https.createServer() with no key/cert refused to listen ("tls config
unavailable") so the listen callback never fired and
test-https-server-async-dispose hung. Node constructs and listens fine
without TLS material — the failure is per-connection, at handshake time.

- tls.rs: build_certless_server_config() — a rustls ServerConfig whose
  cert resolver always returns None, so the server binds/listens and
  each handshake aborts with a fatal alert (Node-equivalent behavior).
- https_server.rs: route the no-PEM-material case to the certless
  config instead of tls_config: None.
- Export kConnectionsCheckingInterval from the http module arm
  (_http_server aliases to http in cjs_wrap) as a sentinel string key;
  server[k] resolves through the ext-http server handle dispatch to a
  minimal {_destroyed} Timeout shape, tracked on HttpServer and set by
  all three close paths (http/https/http2).
@proggeramlug proggeramlug merged commit 4059328 into main Jun 11, 2026
13 checks passed
@proggeramlug proggeramlug deleted the fix/https-async-dispose-4974 branch June 11, 2026 10:39
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.

node:https: 'tls config unavailable; refusing to listen' under async-dispose (test-https-server-async-dispose)

1 participant