Allow a resolver to provide the remote connection token
This commit is contained in:
parent
40cf6489c9
commit
7b40975fd7
|
@ -195,7 +195,7 @@ export function activate(context: vscode.ExtensionContext) {
|
||||||
proxyServer.listen(0, () => {
|
proxyServer.listen(0, () => {
|
||||||
const port = (<net.AddressInfo>proxyServer.address()).port;
|
const port = (<net.AddressInfo>proxyServer.address()).port;
|
||||||
outputChannel.appendLine(`Going through proxy at port ${port}`);
|
outputChannel.appendLine(`Going through proxy at port ${port}`);
|
||||||
res({ host: '127.0.0.1', port });
|
res(new vscode.ResolvedAuthority('127.0.0.1', port));
|
||||||
});
|
});
|
||||||
context.subscriptions.push({
|
context.subscriptions.push({
|
||||||
dispose: () => {
|
dispose: () => {
|
||||||
|
|
|
@ -17,11 +17,13 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot
|
||||||
public readonly onDidChangeConnectionData = this._onDidChangeConnectionData.event;
|
public readonly onDidChangeConnectionData = this._onDidChangeConnectionData.event;
|
||||||
|
|
||||||
private readonly _cache: Map<string, ResolverResult>;
|
private readonly _cache: Map<string, ResolverResult>;
|
||||||
|
private readonly _connectionToken: string | undefined;
|
||||||
private readonly _connectionTokens: Map<string, string>;
|
private readonly _connectionTokens: Map<string, string>;
|
||||||
|
|
||||||
constructor(resourceUriProvider: ((uri: URI) => URI) | undefined) {
|
constructor(connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined) {
|
||||||
super();
|
super();
|
||||||
this._cache = new Map<string, ResolverResult>();
|
this._cache = new Map<string, ResolverResult>();
|
||||||
|
this._connectionToken = connectionToken;
|
||||||
this._connectionTokens = new Map<string, string>();
|
this._connectionTokens = new Map<string, string>();
|
||||||
if (resourceUriProvider) {
|
if (resourceUriProvider) {
|
||||||
RemoteAuthorities.setDelegate(resourceUriProvider);
|
RemoteAuthorities.setDelegate(resourceUriProvider);
|
||||||
|
@ -43,7 +45,7 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const resolverResult = this._cache.get(authority)!;
|
const resolverResult = this._cache.get(authority)!;
|
||||||
const connectionToken = this._connectionTokens.get(authority);
|
const connectionToken = this._connectionTokens.get(authority) || this._connectionToken;
|
||||||
return {
|
return {
|
||||||
host: resolverResult.authority.host,
|
host: resolverResult.authority.host,
|
||||||
port: resolverResult.authority.port,
|
port: resolverResult.authority.port,
|
||||||
|
@ -52,11 +54,12 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot
|
||||||
}
|
}
|
||||||
|
|
||||||
private _doResolveAuthority(authority: string): ResolverResult {
|
private _doResolveAuthority(authority: string): ResolverResult {
|
||||||
|
const connectionToken = this._connectionTokens.get(authority) || this._connectionToken;
|
||||||
if (authority.indexOf(':') >= 0) {
|
if (authority.indexOf(':') >= 0) {
|
||||||
const pieces = authority.split(':');
|
const pieces = authority.split(':');
|
||||||
return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10) } };
|
return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10), connectionToken } };
|
||||||
}
|
}
|
||||||
return { authority: { authority, host: authority, port: 80 } };
|
return { authority: { authority, host: authority, port: 80, connectionToken } };
|
||||||
}
|
}
|
||||||
|
|
||||||
_clearResolvedAuthority(authority: string): void {
|
_clearResolvedAuthority(authority: string): void {
|
||||||
|
|
|
@ -70,6 +70,7 @@ interface ISimpleConnectionOptions {
|
||||||
commit: string | undefined;
|
commit: string | undefined;
|
||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
connectionToken: string | undefined;
|
||||||
reconnectionToken: string;
|
reconnectionToken: string;
|
||||||
reconnectionProtocol: PersistentProtocol | null;
|
reconnectionProtocol: PersistentProtocol | null;
|
||||||
socketFactory: ISocketFactory;
|
socketFactory: ISocketFactory;
|
||||||
|
@ -169,10 +170,9 @@ async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptio
|
||||||
});
|
});
|
||||||
|
|
||||||
options.logService.trace(`${logPrefix} 3/6. sending AuthRequest control message.`);
|
options.logService.trace(`${logPrefix} 3/6. sending AuthRequest control message.`);
|
||||||
// TODO@vs-remote: use real nonce here
|
|
||||||
const authRequest: AuthRequest = {
|
const authRequest: AuthRequest = {
|
||||||
type: 'auth',
|
type: 'auth',
|
||||||
auth: '00000000000000000000'
|
auth: options.connectionToken || '00000000000000000000'
|
||||||
};
|
};
|
||||||
protocol.sendControl(VSBuffer.fromString(JSON.stringify(authRequest)));
|
protocol.sendControl(VSBuffer.fromString(JSON.stringify(authRequest)));
|
||||||
});
|
});
|
||||||
|
@ -254,11 +254,12 @@ export interface IConnectionOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolveConnectionOptions(options: IConnectionOptions, reconnectionToken: string, reconnectionProtocol: PersistentProtocol | null): Promise<ISimpleConnectionOptions> {
|
async function resolveConnectionOptions(options: IConnectionOptions, reconnectionToken: string, reconnectionProtocol: PersistentProtocol | null): Promise<ISimpleConnectionOptions> {
|
||||||
const { host, port } = await options.addressProvider.getAddress();
|
const { host, port, connectionToken } = await options.addressProvider.getAddress();
|
||||||
return {
|
return {
|
||||||
commit: options.commit,
|
commit: options.commit,
|
||||||
host: host,
|
host: host,
|
||||||
port: port,
|
port: port,
|
||||||
|
connectionToken: connectionToken,
|
||||||
reconnectionToken: reconnectionToken,
|
reconnectionToken: reconnectionToken,
|
||||||
reconnectionProtocol: reconnectionProtocol,
|
reconnectionProtocol: reconnectionProtocol,
|
||||||
socketFactory: options.socketFactory,
|
socketFactory: options.socketFactory,
|
||||||
|
@ -270,6 +271,7 @@ async function resolveConnectionOptions(options: IConnectionOptions, reconnectio
|
||||||
export interface IAddress {
|
export interface IAddress {
|
||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
connectionToken: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAddressProvider {
|
export interface IAddressProvider {
|
||||||
|
|
|
@ -12,6 +12,7 @@ export interface ResolvedAuthority {
|
||||||
readonly authority: string;
|
readonly authority: string;
|
||||||
readonly host: string;
|
readonly host: string;
|
||||||
readonly port: number;
|
readonly port: number;
|
||||||
|
readonly connectionToken: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResolvedOptions {
|
export interface ResolvedOptions {
|
||||||
|
|
|
@ -87,6 +87,9 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot
|
||||||
if (this._resolveAuthorityRequests.has(resolvedAuthority.authority)) {
|
if (this._resolveAuthorityRequests.has(resolvedAuthority.authority)) {
|
||||||
const request = this._resolveAuthorityRequests.get(resolvedAuthority.authority)!;
|
const request = this._resolveAuthorityRequests.get(resolvedAuthority.authority)!;
|
||||||
RemoteAuthorities.set(resolvedAuthority.authority, resolvedAuthority.host, resolvedAuthority.port);
|
RemoteAuthorities.set(resolvedAuthority.authority, resolvedAuthority.host, resolvedAuthority.port);
|
||||||
|
if (resolvedAuthority.connectionToken) {
|
||||||
|
RemoteAuthorities.setConnectionToken(resolvedAuthority.authority, resolvedAuthority.connectionToken);
|
||||||
|
}
|
||||||
request.resolve({ authority: resolvedAuthority, options });
|
request.resolve({ authority: resolvedAuthority, options });
|
||||||
this._onDidChangeConnectionData.fire();
|
this._onDidChangeConnectionData.fire();
|
||||||
}
|
}
|
||||||
|
|
3
src/vs/vscode.proposed.d.ts
vendored
3
src/vs/vscode.proposed.d.ts
vendored
|
@ -181,8 +181,9 @@ declare module 'vscode' {
|
||||||
export class ResolvedAuthority {
|
export class ResolvedAuthority {
|
||||||
readonly host: string;
|
readonly host: string;
|
||||||
readonly port: number;
|
readonly port: number;
|
||||||
|
readonly connectionToken: string | undefined;
|
||||||
|
|
||||||
constructor(host: string, port: number);
|
constructor(host: string, port: number, connectionToken?: string);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResolvedOptions {
|
export interface ResolvedOptions {
|
||||||
|
|
|
@ -651,7 +651,8 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
|
||||||
const authority: ResolvedAuthority = {
|
const authority: ResolvedAuthority = {
|
||||||
authority: remoteAuthority,
|
authority: remoteAuthority,
|
||||||
host: result.host,
|
host: result.host,
|
||||||
port: result.port
|
port: result.port,
|
||||||
|
connectionToken: result.connectionToken
|
||||||
};
|
};
|
||||||
const options: ResolvedOptions = {
|
const options: ResolvedOptions = {
|
||||||
extensionHostEnv: result.extensionHostEnv
|
extensionHostEnv: result.extensionHostEnv
|
||||||
|
|
|
@ -433,16 +433,23 @@ export class Selection extends Range {
|
||||||
export class ResolvedAuthority {
|
export class ResolvedAuthority {
|
||||||
readonly host: string;
|
readonly host: string;
|
||||||
readonly port: number;
|
readonly port: number;
|
||||||
|
readonly connectionToken: string | undefined;
|
||||||
|
|
||||||
constructor(host: string, port: number) {
|
constructor(host: string, port: number, connectionToken?: string) {
|
||||||
if (typeof host !== 'string' || host.length === 0) {
|
if (typeof host !== 'string' || host.length === 0) {
|
||||||
throw illegalArgument('host');
|
throw illegalArgument('host');
|
||||||
}
|
}
|
||||||
if (typeof port !== 'number' || port === 0 || Math.round(port) !== port) {
|
if (typeof port !== 'number' || port === 0 || Math.round(port) !== port) {
|
||||||
throw illegalArgument('port');
|
throw illegalArgument('port');
|
||||||
}
|
}
|
||||||
|
if (typeof connectionToken !== 'undefined') {
|
||||||
|
if (typeof connectionToken !== 'string' || connectionToken.length === 0 || !/^[0-9A-Za-z\-]+$/.test(connectionToken)) {
|
||||||
|
throw illegalArgument('connectionToken');
|
||||||
|
}
|
||||||
|
}
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = Math.round(port);
|
this.port = Math.round(port);
|
||||||
|
this.connectionToken = connectionToken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,12 +179,14 @@ class BrowserMain extends Disposable {
|
||||||
const logService = new BufferLogService(getLogLevel(environmentService));
|
const logService = new BufferLogService(getLogLevel(environmentService));
|
||||||
serviceCollection.set(ILogService, logService);
|
serviceCollection.set(ILogService, logService);
|
||||||
|
|
||||||
|
const connectionToken = environmentService.options.connectionToken || this.getCookieValue('vscode-tkn');
|
||||||
|
|
||||||
// Remote
|
// Remote
|
||||||
const remoteAuthorityResolverService = new RemoteAuthorityResolverService(this.configuration.resourceUriProvider);
|
const remoteAuthorityResolverService = new RemoteAuthorityResolverService(connectionToken, this.configuration.resourceUriProvider);
|
||||||
serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService);
|
serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService);
|
||||||
|
|
||||||
// Signing
|
// Signing
|
||||||
const signService = new SignService(environmentService.options.connectionToken || this.getCookieValue('vscode-tkn'));
|
const signService = new SignService(connectionToken);
|
||||||
serviceCollection.set(ISignService, signService);
|
serviceCollection.set(ISignService, signService);
|
||||||
|
|
||||||
// Remote Agent
|
// Remote Agent
|
||||||
|
|
|
@ -265,7 +265,8 @@ export class ExtensionHostManager extends Disposable {
|
||||||
authority: {
|
authority: {
|
||||||
authority: remoteAuthority,
|
authority: remoteAuthority,
|
||||||
host: pieces[0],
|
host: pieces[0],
|
||||||
port: parseInt(pieces[1], 10)
|
port: parseInt(pieces[1], 10),
|
||||||
|
connectionToken: undefined
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ export class RemoteExtensionHost extends Disposable implements IExtensionHost {
|
||||||
addressProvider: {
|
addressProvider: {
|
||||||
getAddress: async () => {
|
getAddress: async () => {
|
||||||
const { authority } = await this.remoteAuthorityResolverService.resolveAuthority(this._initDataProvider.remoteAuthority);
|
const { authority } = await this.remoteAuthorityResolverService.resolveAuthority(this._initDataProvider.remoteAuthority);
|
||||||
return { host: authority.host, port: authority.port };
|
return { host: authority.host, port: authority.port, connectionToken: authority.connectionToken };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
signService: this._signService,
|
signService: this._signService,
|
||||||
|
|
|
@ -183,7 +183,7 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon
|
||||||
this._onReconnecting.fire(undefined);
|
this._onReconnecting.fire(undefined);
|
||||||
}
|
}
|
||||||
const { authority } = await this._remoteAuthorityResolverService.resolveAuthority(this.remoteAuthority);
|
const { authority } = await this._remoteAuthorityResolverService.resolveAuthority(this.remoteAuthority);
|
||||||
return { host: authority.host, port: authority.port };
|
return { host: authority.host, port: authority.port, connectionToken: authority.connectionToken };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
signService: this._signService,
|
signService: this._signService,
|
||||||
|
|
Loading…
Reference in a new issue