Skip to content

node:tls: SNICallback, new tls.TLSSocket(socket, {isServer}), and ALPNProtocols not supported #1438

Open

Description

@saboursepideh

Version: scriptc 0.3.6, Linux x64

Use case: an intercepting HTTPS proxy that terminates TLS for many hostnames on a single listener, or upgrades a raw socket after an HTTP CONNECT. A fixed-cert tls.createServer({key, cert}) works, but the pieces needed for the multi-host case are missing.

1. SNICallback

import * as tls from "node:tls";
import * as fs from "node:fs";
const ctx = tls.createSecureContext({ key: fs.readFileSync("k.pem"), cert: fs.readFileSync("c.pem") });
tls.createServer({ SNICallback: (name: string, cb: (e: Error | null, c?: tls.SecureContext) => void) => cb(null, ctx) },
  (s) => s.end("hi")).listen(0);

→ SC2020: 'tls.createServer option 'SNICallback'' is part of the standard library types but has no scriptc lowering yet

2. Wrapping an existing socket

import * as tls from "node:tls";
import * as net from "node:net";
net.createServer((raw) => {
  new tls.TLSSocket(raw, { isServer: true, key, cert }).end("hi");
}).listen(0);

→ SC0001: Property 'TLSSocket' does not exist on type 'typeof import("node:tls")'.
(Equivalently, server.emit("connection", rawSocket) or tls.connect({ socket }) would cover the client side.)

3. ALPN on tls.connect

const s = tls.connect({ host: "example.com", port: 443, servername: "example.com", ALPNProtocols: ["h2", "http/1.1"] },
  () => console.log(s.alpnProtocol));

Compiles, then fails at runtime:
Uncaught Error: tls.connect option 'ALPNProtocols' has no static lowering — port/host/rejectUnauthorized/ca/servername are the honestly-implemented members of a runtime options record
Server-side ALPNProtocols would be useful too.

Current workaround

Spin up one loopback https.createServer per hostname and pipe the CONNECT socket into it. It works, but it adds an extra hop and costs a listener per host.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions