mirror of https://github.com/grpc/grpc-node.git
Merge pull request #1369 from mrfelton/proxy-tls
grpc-js: initiate tls connection through http proxy
This commit is contained in:
commit
c5424a53a9
|
|
@ -18,9 +18,11 @@
|
||||||
import { URL } from 'url';
|
import { URL } from 'url';
|
||||||
import { log } from './logging';
|
import { log } from './logging';
|
||||||
import { LogVerbosity } from './constants';
|
import { LogVerbosity } from './constants';
|
||||||
|
import { getDefaultAuthority } from './resolver';
|
||||||
import { parseTarget } from './resolver-dns';
|
import { parseTarget } from './resolver-dns';
|
||||||
import { Socket } from 'net';
|
import { Socket } from 'net';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
|
import * as tls from 'tls';
|
||||||
import * as logging from './logging';
|
import * as logging from './logging';
|
||||||
import {
|
import {
|
||||||
SubchannelAddress,
|
SubchannelAddress,
|
||||||
|
|
@ -157,7 +159,8 @@ export interface ProxyConnectionResult {
|
||||||
|
|
||||||
export function getProxiedConnection(
|
export function getProxiedConnection(
|
||||||
address: SubchannelAddress,
|
address: SubchannelAddress,
|
||||||
channelOptions: ChannelOptions
|
channelOptions: ChannelOptions,
|
||||||
|
connectionOptions: tls.ConnectionOptions
|
||||||
): Promise<ProxyConnectionResult> {
|
): Promise<ProxyConnectionResult> {
|
||||||
if (!('grpc.http_connect_target' in channelOptions)) {
|
if (!('grpc.http_connect_target' in channelOptions)) {
|
||||||
return Promise.resolve<ProxyConnectionResult>({});
|
return Promise.resolve<ProxyConnectionResult>({});
|
||||||
|
|
@ -202,10 +205,25 @@ export function getProxiedConnection(
|
||||||
' through proxy ' +
|
' through proxy ' +
|
||||||
proxyAddressString
|
proxyAddressString
|
||||||
);
|
);
|
||||||
resolve({
|
if ('secureContext' in connectionOptions) {
|
||||||
socket,
|
/* The proxy is connecting to a TLS server, so upgrade this socket
|
||||||
realTarget,
|
* connection to a TLS connection.
|
||||||
});
|
* This is a workaround for https://github.com/nodejs/node/issues/32922
|
||||||
|
* See https://github.com/grpc/grpc-node/pull/1369 for more info. */
|
||||||
|
const cts = tls.connect({
|
||||||
|
...connectionOptions,
|
||||||
|
host: getDefaultAuthority(realTarget),
|
||||||
|
socket: socket,
|
||||||
|
}, () => {
|
||||||
|
resolve({ socket: cts, realTarget });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
resolve({
|
||||||
|
socket,
|
||||||
|
realTarget,
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log(
|
log(
|
||||||
LogVerbosity.ERROR,
|
LogVerbosity.ERROR,
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import * as logging from './logging';
|
||||||
import { LogVerbosity } from './constants';
|
import { LogVerbosity } from './constants';
|
||||||
import { getProxiedConnection, ProxyConnectionResult } from './http_proxy';
|
import { getProxiedConnection, ProxyConnectionResult } from './http_proxy';
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
|
import { ConnectionOptions } from 'tls';
|
||||||
|
|
||||||
const clientVersion = require('../../package.json').version;
|
const clientVersion = require('../../package.json').version;
|
||||||
|
|
||||||
|
|
@ -300,7 +301,9 @@ export class Subchannel {
|
||||||
connectionOptions.servername = sslTargetNameOverride;
|
connectionOptions.servername = sslTargetNameOverride;
|
||||||
}
|
}
|
||||||
if (proxyConnectionResult.socket) {
|
if (proxyConnectionResult.socket) {
|
||||||
connectionOptions.socket = proxyConnectionResult.socket;
|
connectionOptions.createConnection = (authority, option) => {
|
||||||
|
return proxyConnectionResult.socket!;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* In all but the most recent versions of Node, http2.connect does not use
|
/* In all but the most recent versions of Node, http2.connect does not use
|
||||||
|
|
@ -317,6 +320,7 @@ export class Subchannel {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionOptions = Object.assign(
|
connectionOptions = Object.assign(
|
||||||
connectionOptions,
|
connectionOptions,
|
||||||
this.subchannelAddress
|
this.subchannelAddress
|
||||||
|
|
@ -412,7 +416,37 @@ export class Subchannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private startConnectingInternal() {
|
private startConnectingInternal() {
|
||||||
getProxiedConnection(this.subchannelAddress, this.options).then(
|
/* Pass connection options through to the proxy so that it's able to
|
||||||
|
* upgrade it's connection to support tls if needed.
|
||||||
|
* This is a workaround for https://github.com/nodejs/node/issues/32922
|
||||||
|
* See https://github.com/grpc/grpc-node/pull/1369 for more info. */
|
||||||
|
const connectionOptions: ConnectionOptions =
|
||||||
|
this.credentials._getConnectionOptions() || {};
|
||||||
|
|
||||||
|
if ('secureContext' in connectionOptions) {
|
||||||
|
connectionOptions.ALPNProtocols = ['h2'];
|
||||||
|
// If provided, the value of grpc.ssl_target_name_override should be used
|
||||||
|
// to override the target hostname when checking server identity.
|
||||||
|
// This option is used for testing only.
|
||||||
|
if (this.options['grpc.ssl_target_name_override']) {
|
||||||
|
const sslTargetNameOverride = this.options[
|
||||||
|
'grpc.ssl_target_name_override'
|
||||||
|
]!;
|
||||||
|
connectionOptions.checkServerIdentity = (
|
||||||
|
host: string,
|
||||||
|
cert: PeerCertificate
|
||||||
|
): Error | undefined => {
|
||||||
|
return checkServerIdentity(sslTargetNameOverride, cert);
|
||||||
|
};
|
||||||
|
connectionOptions.servername = sslTargetNameOverride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getProxiedConnection(
|
||||||
|
this.subchannelAddress,
|
||||||
|
this.options,
|
||||||
|
connectionOptions
|
||||||
|
).then(
|
||||||
(result) => {
|
(result) => {
|
||||||
this.createSession(result);
|
this.createSession(result);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue