1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-24 15:19:26 -05:00

fix(node:tls): set TLSSocket.alpnProtocol for client connections (#26476)

Towards https://github.com/denoland/deno/issues/26127
This commit is contained in:
Satya Rohith 2024-10-23 13:17:43 +05:30 committed by GitHub
parent be969cb532
commit 92ed4d38db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 43 additions and 1 deletions

View file

@ -68,6 +68,7 @@ export class TLSSocket extends net.Socket {
secureConnecting: boolean; secureConnecting: boolean;
_SNICallback: any; _SNICallback: any;
servername: string | null; servername: string | null;
alpnProtocol: string | boolean | null;
alpnProtocols: string[] | null; alpnProtocols: string[] | null;
authorized: boolean; authorized: boolean;
authorizationError: any; authorizationError: any;
@ -114,6 +115,7 @@ export class TLSSocket extends net.Socket {
this.secureConnecting = true; this.secureConnecting = true;
this._SNICallback = null; this._SNICallback = null;
this.servername = null; this.servername = null;
this.alpnProtocol = null;
this.alpnProtocols = tlsOptions.ALPNProtocols; this.alpnProtocols = tlsOptions.ALPNProtocols;
this.authorized = false; this.authorized = false;
this.authorizationError = null; this.authorizationError = null;
@ -151,10 +153,21 @@ export class TLSSocket extends net.Socket {
handle.afterConnect = async (req: any, status: number) => { handle.afterConnect = async (req: any, status: number) => {
try { try {
const conn = await Deno.startTls(handle[kStreamBaseField], options); const conn = await Deno.startTls(handle[kStreamBaseField], options);
try {
const hs = await conn.handshake();
if (hs.alpnProtocol) {
tlssock.alpnProtocol = hs.alpnProtocol;
} else {
tlssock.alpnProtocol = false;
}
} catch {
// Don't interrupt "secure" event to let the first read/write
// operation emit the error.
}
handle[kStreamBaseField] = conn; handle[kStreamBaseField] = conn;
tlssock.emit("secure"); tlssock.emit("secure");
tlssock.removeListener("end", onConnectEnd); tlssock.removeListener("end", onConnectEnd);
} catch { } catch (_) {
// TODO(kt3k): Handle this // TODO(kt3k): Handle this
} }
return afterConnect.call(handle, req, status); return afterConnect.call(handle, req, status);
@ -269,6 +282,7 @@ export class ServerImpl extends EventEmitter {
// Creates TCP handle and socket directly from Deno.TlsConn. // Creates TCP handle and socket directly from Deno.TlsConn.
// This works as TLS socket. We don't use TLSSocket class for doing // This works as TLS socket. We don't use TLSSocket class for doing
// this because Deno.startTls only supports client side tcp connection. // this because Deno.startTls only supports client side tcp connection.
// TODO(@satyarohith): set TLSSocket.alpnProtocol when we use TLSSocket class.
const handle = new TCP(TCPConstants.SOCKET, await listener.accept()); const handle = new TCP(TCPConstants.SOCKET, await listener.accept());
const socket = new net.Socket({ handle }); const socket = new net.Socket({ handle });
this.emit("secureConnection", socket); this.emit("secureConnection", socket);

View file

@ -235,3 +235,31 @@ Deno.test("tls.rootCertificates is not empty", () => {
(tls.rootCertificates as string[]).push("new cert"); (tls.rootCertificates as string[]).push("new cert");
}, TypeError); }, TypeError);
}); });
Deno.test("TLSSocket.alpnProtocol is set for client", async () => {
const listener = Deno.listenTls({
hostname: "localhost",
port: 0,
key,
cert,
alpnProtocols: ["a"],
});
const outgoing = tls.connect({
host: "::1",
servername: "localhost",
port: listener.addr.port,
ALPNProtocols: ["a"],
secureContext: {
ca: rootCaCert,
// deno-lint-ignore no-explicit-any
} as any,
});
const conn = await listener.accept();
const handshake = await conn.handshake();
assertEquals(handshake.alpnProtocol, "a");
conn.close();
outgoing.destroy();
listener.close();
await new Promise((resolve) => outgoing.on("close", resolve));
});