fix(tsconnect/wasm): close conn on upgradeTLS configuration errors too

Previously only a handshake failure closed the underlying conn;
configuration errors (malformed caCerts PEM, bad cert/key pair)
returned with the conn still open, while the JS wrapper treats every
upgradeTLS rejection as fatal and marks the conn closed — leaking a
live Go conn that could no longer be closed from JS. Close on every
error path so the JS contract (any rejection after validation is
fatal) holds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XfRgMke8p7QDxD5QM5thxH
This commit was merged in pull request #14.
This commit is contained in:
2026-07-12 11:28:33 +00:00
parent 81e37f8812
commit 721194dfb5
+8 -3
View File
@@ -1482,9 +1482,11 @@ func wrapConn(conn net.Conn) map[string]any {
}),
// upgradeTLS wraps the conn in TLS in place (STARTTLS-style) and
// returns a new wrapped conn sharing the same underlying net.Conn;
// the old handle must not be used afterward. On handshake failure
// the underlying conn is closed. With isServer, certPem and keyPem
// are required; otherwise client options as in dialTLS apply.
// the old handle must not be used afterward. On any failure
// configuration or handshake — the underlying conn is closed, so
// callers can treat every rejection as fatal to the connection.
// With isServer, certPem and keyPem are required; otherwise client
// options as in dialTLS apply.
"upgradeTLS": js.FuncOf(func(this js.Value, args []js.Value) any {
opts := js.Undefined()
if len(args) > 0 {
@@ -1497,16 +1499,19 @@ func wrapConn(conn net.Conn) map[string]any {
certPem := opts.Get("certPem")
keyPem := opts.Get("keyPem")
if certPem.Type() != js.TypeString || keyPem.Type() != js.TypeString {
conn.Close()
return nil, fmt.Errorf("upgradeTLS: certPem and keyPem are required when isServer is set")
}
cert, err := tls.X509KeyPair([]byte(certPem.String()), []byte(keyPem.String()))
if err != nil {
conn.Close()
return nil, fmt.Errorf("upgradeTLS: parsing cert/key: %w", err)
}
tlsConn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{cert}})
} else {
cfg, err := tlsClientConfigFromJS("", opts)
if err != nil {
conn.Close()
return nil, err
}
tlsConn = tls.Client(conn, cfg)