Skip to content

Commit

Permalink
Merge pull request #2895 from murgatroid99/grpc-js_interop_fix
Browse files Browse the repository at this point in the history
grpc-js: Connect with https scheme when using TLS
  • Loading branch information
murgatroid99 authored Jan 30, 2025
2 parents 023b086 + 9569f20 commit d2462ca
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 16 deletions.
28 changes: 21 additions & 7 deletions packages/grpc-js/src/channel-credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ export interface VerifyOptions {
rejectUnauthorized?: boolean;
}

export interface SecureConnectResult {
socket: Socket;
secure: boolean;
}

export interface SecureConnector {
connect(socket: Socket): Promise<Socket>;
connect(socket: Socket): Promise<SecureConnectResult>;
getCallCredentials(): CallCredentials;
destroy(): void;
}
Expand Down Expand Up @@ -178,7 +183,10 @@ class InsecureChannelCredentialsImpl extends ChannelCredentials {
_createSecureConnector(channelTarget: GrpcUri, options: ChannelOptions, callCredentials?: CallCredentials): SecureConnector {
return {
connect(socket) {
return Promise.resolve(socket);
return Promise.resolve({
socket,
secure: false
});
},
getCallCredentials: () => {
return callCredentials ?? CallCredentials.createEmpty();
Expand Down Expand Up @@ -247,14 +255,17 @@ function getConnectionOptions(secureContext: SecureContext, verifyOptions: Verif
class SecureConnectorImpl implements SecureConnector {
constructor(private connectionOptions: ConnectionOptions, private callCredentials: CallCredentials) {
}
connect(socket: Socket): Promise<Socket> {
connect(socket: Socket): Promise<SecureConnectResult> {
const tlsConnectOptions: ConnectionOptions = {
socket: socket,
...this.connectionOptions
};
return new Promise<Socket>((resolve, reject) => {
return new Promise<SecureConnectResult>((resolve, reject) => {
const tlsSocket = tlsConnect(tlsConnectOptions, () => {
resolve(tlsSocket)
resolve({
socket: tlsSocket,
secure: true
})
});
tlsSocket.on('error', (error: Error) => {
reject(error);
Expand Down Expand Up @@ -316,7 +327,7 @@ class CertificateProviderChannelCredentialsImpl extends ChannelCredentials {
private static SecureConnectorImpl = class implements SecureConnector {
constructor(private parent: CertificateProviderChannelCredentialsImpl, private channelTarget: GrpcUri, private options: ChannelOptions, private callCredentials: CallCredentials) {}

connect(socket: Socket): Promise<Socket> {
connect(socket: Socket): Promise<SecureConnectResult> {
return new Promise(async (resolve, reject) => {
const secureContext = await this.parent.getSecureContext();
if (!secureContext) {
Expand All @@ -329,7 +340,10 @@ class CertificateProviderChannelCredentialsImpl extends ChannelCredentials {
...connnectionOptions
}
const tlsSocket = tlsConnect(tlsConnectOptions, () => {
resolve(tlsSocket)
resolve({
socket: tlsSocket,
secure: true
});
});
tlsSocket.on('error', (error: Error) => {
reject(error);
Expand Down
2 changes: 1 addition & 1 deletion packages/grpc-js/src/experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,5 @@ export {
FileWatcherCertificateProvider,
FileWatcherCertificateProviderConfig
} from './certificate-provider';
export { createCertificateProviderChannelCredentials, SecureConnector } from './channel-credentials';
export { createCertificateProviderChannelCredentials, SecureConnector, SecureConnectResult } from './channel-credentials';
export { SUBCHANNEL_ARGS_EXCLUDE_KEY_PREFIX } from './internal-channel';
17 changes: 9 additions & 8 deletions packages/grpc-js/src/transport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
TLSSocket,
} from 'tls';
import { PartialStatusObject } from './call-interface';
import { SecureConnector } from './channel-credentials';
import { SecureConnector, SecureConnectResult } from './channel-credentials';
import { ChannelOptions } from './channel-options';
import {
ChannelzCallTracker,
Expand Down Expand Up @@ -651,7 +651,7 @@ export class Http2SubchannelConnector implements SubchannelConnector {
}

private createSession(
underlyingConnection: Socket,
secureConnectResult: SecureConnectResult,
address: SubchannelAddress,
options: ChannelOptions
): Promise<Http2Transport> {
Expand All @@ -669,10 +669,11 @@ export class Http2SubchannelConnector implements SubchannelConnector {
remoteName = uriToString(parsedTarget);
}
}
const scheme = secureConnectResult.secure ? 'https' : 'http';
const targetPath = getDefaultAuthority(realTarget);
const session = http2.connect(`http://${targetPath}`, {
const session = http2.connect(`${scheme}://${targetPath}`, {
createConnection: (authority, option) => {
return underlyingConnection;
return secureConnectResult.socket;
},
settings: {
initialWindowSize:
Expand Down Expand Up @@ -736,14 +737,14 @@ export class Http2SubchannelConnector implements SubchannelConnector {
return Promise.reject();
}
let tcpConnection: net.Socket | null = null;
let secureConnection: net.Socket | null = null;
let secureConnectResult: SecureConnectResult | null = null;
try {
tcpConnection = await this.tcpConnect(address, options);
secureConnection = await secureConnector.connect(tcpConnection);
return this.createSession(secureConnection, address, options);
secureConnectResult = await secureConnector.connect(tcpConnection);
return this.createSession(secureConnectResult, address, options);
} catch (e) {
tcpConnection?.destroy();
secureConnection?.destroy();
secureConnectResult?.socket.destroy();
throw e;
}
}
Expand Down

0 comments on commit d2462ca

Please sign in to comment.