Repository navigation
node:http, node:net: a plain socket has none of TLSSocket's property names - #45659
dylan-conway wants to merge 2 commits into
Conversation
|
Updated 4:03 AM PT - Oct 17th, 2026
❌ @dylan-conway, your commit 95fbba0 has 2 failures in
🧪 To try this PR locally: bunx bun-pr 45659That installs a local version of the PR into your bun-45659 --bun |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
WalkthroughHTTP server socket creation now uses separate plain and TLS socket classes. TLS-only properties are limited to TLS sockets. Net socket setup and the client-error callback argument list also changed. ChangesHTTP and net socket TLS properties
Suggested reviewers: Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to
|
There was a problem hiding this comment.
Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.
Beyond the inline findings, I also checked that every in-tree reader of encrypted / _secureEstablished / authorized on an HTTP server socket (src/js/thirdparty/ws.ts:3302, the net.ts readStop/half-open guards) tests truthiness, so a missing property behaves like the old false; that the base NodeHTTPServerSocket constructor never reads those names before the TLS subclass's field initialisers run; and that the net.ts guard does not drop servername for TLS clients, since Socket.prototype.connect still assigns it from the TLS options at src/js/node/net.ts:2365.
Extended reasoning...
The change moves TLS-only property names off the shared HTTP server socket into a subclass constructed only for TLS connections, and stops net.Socket.connect from assigning servername on plain sockets; it touches node:http/node:net compat surface but no auth, crypto or input-parsing logic. Two confirmed findings are posted inline, so a human look is already signalled; this note records the adjacent concerns that were examined and ruled out.
…LS options, and a plain net.Server socket has no _requestCert
What
On a plain (non-TLS) connection,
node:httpandnode:netsockets had property names that onlytls.TLSSockethas in Node:encrypted,_secureEstablished,authorized,authorizationError,servername,_requestCert,_rejectUnauthorized.Why it matters
"encrypted" in socketis a common way to tell aTLSSocketfrom anet.Socket. With an ownencrypted: false, that test is true for every plain HTTP request.@adonisjs/http-serverdoes exactly this, sorequest.protocol()returned"https"andrequest.secure()returnedtrueon plain HTTP.Cause and fix
src/js/node/_http_server.ts, one class for both. One socket class served plain and TLS connections. Its constructor always assignedencryptedand_secureEstablished, and the three TLS getters lived on the shared prototype. The TLS-only members are now in a subclass that only a TLS connection gets.src/js/node/_http_server.ts, one source for "is this TLS". The three places that make a socket each decided it differently: from the localtlsoflisten(), from the constructor's options, and from a native flag. Only the first knows aboutlisten({ tls }). The TLS options of alisten()call are now on that call'slistenerGeneration, which all three already pass. The class, the'secureConnection'event,requestCertandresetAndDestroy()read them there. Theencryptedconstructor argument and thesslargument of the nativeclientErrorcallback are gone.src/js/node/net.ts.Socket.prototype.connectassignedthis.servernameon every socket, and the accept path assigned_requestCertand_rejectUnauthorizedon every socket. Both now do so only for a TLS socket.Every reader of these names in
src/jsthat a plain socket can reach tests truthiness, so a missing property behaves like the oldfalse/undefined.Behaviour
"bug" means different from Node 26.7.
listen({ tls })does not exist in Node. What is right for it is whathttps.createServer(options)gives.bug -> bug
_secureEstablishedandencryptedinObject.keys(req.socket)on anhttps.Serversocketbug -> non-bug
http.Serversocket ('connection',req.socket)encrypted,_secureEstablished,authorized,authorizationError,servernameres.socketofhttp.get()servernamereq.socket.authorized = trueon a plain socket, strict modeTypeErrornet.connect()socketservernamenet.Serveraccepted_requestCert,_rejectUnauthorizedsocket.servername = "mine"beforeconnect()on a plain socketundefined"mine""mine"http.createServer().listen({ tls })(Bun only):req.socketencrypted=false _secureEstablished=true authorized=undefined authorizationError=undefined servername=undefined,'secureConnection'not emittedencrypted=true _secureEstablished=true authorized=false authorizationError=null servername="localhost",'secureConnection'emittedWith
listen({ tls: { requestCert: true, ... } })and a client certificate that verifies,authorizedistrue(main:undefined).non-bug -> bug
None.
non-bug -> non-bug
None.
Tests
node-http.test.ts"is not marked encrypted (Express believesprotocol=httpwhen HTTPS request #5867)" assertedencrypted === false, which is the behaviour that differs from Node. It now asserts that none of five names isinthe'connection'socket,req.socket, or the client'sres.socket. Fails on 1.4.3.node-http.test.ts"the socket of ... is marked encrypted (Express believesprotocol=httpwhen HTTPS request #5867)" runs forhttps.createServer(options)and forhttp.createServer().listen({ tls }), and checks all five values. On 1.4.3 the first passes (it guards the TLS side) and the second fails.node-net.test.ts"a plain socket has none of TLSSocket's property names" checks the connecting and the accepted socket. Fails on 1.4.3.node-http.test.tsandnode-net.test.tspass in full on a debug build.