mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -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:
parent
be969cb532
commit
92ed4d38db
2 changed files with 43 additions and 1 deletions
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue