Skip to content

Commit d2462ca

Browse files
authored
Merge pull request #2895 from murgatroid99/grpc-js_interop_fix
grpc-js: Connect with https scheme when using TLS
2 parents 023b086 + 9569f20 commit d2462ca

File tree

3 files changed

+31
-16
lines changed

3 files changed

+31
-16
lines changed

packages/grpc-js/src/channel-credentials.ts

+21-7
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,13 @@ export interface VerifyOptions {
6363
rejectUnauthorized?: boolean;
6464
}
6565

66+
export interface SecureConnectResult {
67+
socket: Socket;
68+
secure: boolean;
69+
}
70+
6671
export interface SecureConnector {
67-
connect(socket: Socket): Promise<Socket>;
72+
connect(socket: Socket): Promise<SecureConnectResult>;
6873
getCallCredentials(): CallCredentials;
6974
destroy(): void;
7075
}
@@ -178,7 +183,10 @@ class InsecureChannelCredentialsImpl extends ChannelCredentials {
178183
_createSecureConnector(channelTarget: GrpcUri, options: ChannelOptions, callCredentials?: CallCredentials): SecureConnector {
179184
return {
180185
connect(socket) {
181-
return Promise.resolve(socket);
186+
return Promise.resolve({
187+
socket,
188+
secure: false
189+
});
182190
},
183191
getCallCredentials: () => {
184192
return callCredentials ?? CallCredentials.createEmpty();
@@ -247,14 +255,17 @@ function getConnectionOptions(secureContext: SecureContext, verifyOptions: Verif
247255
class SecureConnectorImpl implements SecureConnector {
248256
constructor(private connectionOptions: ConnectionOptions, private callCredentials: CallCredentials) {
249257
}
250-
connect(socket: Socket): Promise<Socket> {
258+
connect(socket: Socket): Promise<SecureConnectResult> {
251259
const tlsConnectOptions: ConnectionOptions = {
252260
socket: socket,
253261
...this.connectionOptions
254262
};
255-
return new Promise<Socket>((resolve, reject) => {
263+
return new Promise<SecureConnectResult>((resolve, reject) => {
256264
const tlsSocket = tlsConnect(tlsConnectOptions, () => {
257-
resolve(tlsSocket)
265+
resolve({
266+
socket: tlsSocket,
267+
secure: true
268+
})
258269
});
259270
tlsSocket.on('error', (error: Error) => {
260271
reject(error);
@@ -316,7 +327,7 @@ class CertificateProviderChannelCredentialsImpl extends ChannelCredentials {
316327
private static SecureConnectorImpl = class implements SecureConnector {
317328
constructor(private parent: CertificateProviderChannelCredentialsImpl, private channelTarget: GrpcUri, private options: ChannelOptions, private callCredentials: CallCredentials) {}
318329

319-
connect(socket: Socket): Promise<Socket> {
330+
connect(socket: Socket): Promise<SecureConnectResult> {
320331
return new Promise(async (resolve, reject) => {
321332
const secureContext = await this.parent.getSecureContext();
322333
if (!secureContext) {
@@ -329,7 +340,10 @@ class CertificateProviderChannelCredentialsImpl extends ChannelCredentials {
329340
...connnectionOptions
330341
}
331342
const tlsSocket = tlsConnect(tlsConnectOptions, () => {
332-
resolve(tlsSocket)
343+
resolve({
344+
socket: tlsSocket,
345+
secure: true
346+
});
333347
});
334348
tlsSocket.on('error', (error: Error) => {
335349
reject(error);

packages/grpc-js/src/experimental.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,5 @@ export {
6363
FileWatcherCertificateProvider,
6464
FileWatcherCertificateProviderConfig
6565
} from './certificate-provider';
66-
export { createCertificateProviderChannelCredentials, SecureConnector } from './channel-credentials';
66+
export { createCertificateProviderChannelCredentials, SecureConnector, SecureConnectResult } from './channel-credentials';
6767
export { SUBCHANNEL_ARGS_EXCLUDE_KEY_PREFIX } from './internal-channel';

packages/grpc-js/src/transport.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
TLSSocket,
2222
} from 'tls';
2323
import { PartialStatusObject } from './call-interface';
24-
import { SecureConnector } from './channel-credentials';
24+
import { SecureConnector, SecureConnectResult } from './channel-credentials';
2525
import { ChannelOptions } from './channel-options';
2626
import {
2727
ChannelzCallTracker,
@@ -651,7 +651,7 @@ export class Http2SubchannelConnector implements SubchannelConnector {
651651
}
652652

653653
private createSession(
654-
underlyingConnection: Socket,
654+
secureConnectResult: SecureConnectResult,
655655
address: SubchannelAddress,
656656
options: ChannelOptions
657657
): Promise<Http2Transport> {
@@ -669,10 +669,11 @@ export class Http2SubchannelConnector implements SubchannelConnector {
669669
remoteName = uriToString(parsedTarget);
670670
}
671671
}
672+
const scheme = secureConnectResult.secure ? 'https' : 'http';
672673
const targetPath = getDefaultAuthority(realTarget);
673-
const session = http2.connect(`http://${targetPath}`, {
674+
const session = http2.connect(`${scheme}://${targetPath}`, {
674675
createConnection: (authority, option) => {
675-
return underlyingConnection;
676+
return secureConnectResult.socket;
676677
},
677678
settings: {
678679
initialWindowSize:
@@ -736,14 +737,14 @@ export class Http2SubchannelConnector implements SubchannelConnector {
736737
return Promise.reject();
737738
}
738739
let tcpConnection: net.Socket | null = null;
739-
let secureConnection: net.Socket | null = null;
740+
let secureConnectResult: SecureConnectResult | null = null;
740741
try {
741742
tcpConnection = await this.tcpConnect(address, options);
742-
secureConnection = await secureConnector.connect(tcpConnection);
743-
return this.createSession(secureConnection, address, options);
743+
secureConnectResult = await secureConnector.connect(tcpConnection);
744+
return this.createSession(secureConnectResult, address, options);
744745
} catch (e) {
745746
tcpConnection?.destroy();
746-
secureConnection?.destroy();
747+
secureConnectResult?.socket.destroy();
747748
throw e;
748749
}
749750
}

0 commit comments

Comments
 (0)