提交 c4b7d109 编写于 作者: A Alex Ross

Use property bag for tunnel creation elevation

Fixes #110795
上级 197f1341
......@@ -26,8 +26,12 @@ export interface TunnelOptions {
label?: string;
}
export interface TunnelCreationInformation {
elevationRequired?: boolean;
}
export interface ITunnelProvider {
forwardPort(tunnelOptions: TunnelOptions): Promise<RemoteTunnel> | undefined;
forwardPort(tunnelOptions: TunnelOptions, tunnelCreationInformation: TunnelCreationInformation): Promise<RemoteTunnel> | undefined;
}
export interface ITunnelService {
......@@ -198,6 +202,10 @@ export abstract class AbstractTunnelService implements ITunnelService {
}
protected abstract retainOrCreateTunnel(addressProvider: IAddressProvider, remoteHost: string, remotePort: number, localPort?: number): Promise<RemoteTunnel> | undefined;
protected isPortPrivileged(port: number): boolean {
return port < 1024;
}
}
export class TunnelService extends AbstractTunnelService {
......@@ -209,7 +217,10 @@ export class TunnelService extends AbstractTunnelService {
}
if (this._tunnelProvider) {
const tunnel = this._tunnelProvider.forwardPort({ remoteAddress: { host: remoteHost, port: remotePort } });
const preferredLocalPort = localPort === undefined ? remotePort : localPort;
const tunnelOptions = { remoteAddress: { host: remoteHost, port: remotePort }, localAddressPort: localPort };
const creationInfo = { elevationRequired: this.isPortPrivileged(preferredLocalPort) };
const tunnel = this._tunnelProvider.forwardPort(tunnelOptions, creationInfo);
if (tunnel) {
this.addTunnelToMap(remoteHost, remotePort, tunnel);
}
......
......@@ -146,7 +146,10 @@ export class TunnelService extends AbstractTunnelService {
}
if (this._tunnelProvider) {
const tunnel = this._tunnelProvider.forwardPort({ remoteAddress: { host: remoteHost, port: remotePort }, localAddressPort: localPort });
const preferredLocalPort = localPort === undefined ? remotePort : localPort;
const creationInfo = { elevationRequired: this.isPortPrivileged(preferredLocalPort) };
const tunnelOptions = { remoteAddress: { host: remoteHost, port: remotePort }, localAddressPort: localPort };
const tunnel = this._tunnelProvider.forwardPort(tunnelOptions, creationInfo);
if (tunnel) {
this.addTunnelToMap(remoteHost, remotePort, tunnel);
}
......
......@@ -223,6 +223,13 @@ declare module 'vscode' {
}
export interface TunnelCreationInformation {
/**
* True when the local operating system will require elevation to use the requested local port.
*/
elevationRequired?: boolean;
}
export type ResolverResult = ResolvedAuthority & ResolvedOptions & TunnelInformation;
export class RemoteAuthorityResolverError extends Error {
......@@ -239,7 +246,7 @@ declare module 'vscode' {
* When not implemented, the core will use its default forwarding logic.
* When implemented, the core will use this to forward ports.
*/
tunnelFactory?: (tunnelOptions: TunnelOptions, elevate?: boolean) => Thenable<Tunnel> | undefined;
tunnelFactory?: (tunnelOptions: TunnelOptions, tunnelCreationInformation: TunnelCreationInformation) => Thenable<Tunnel> | undefined;
/**
* Provides filtering for candidate ports.
......
......@@ -7,7 +7,7 @@ import { MainThreadTunnelServiceShape, IExtHostContext, MainContext, ExtHostCont
import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { IRemoteExplorerService, makeAddress } from 'vs/workbench/services/remote/common/remoteExplorerService';
import { ITunnelProvider, ITunnelService, TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { ITunnelProvider, ITunnelService, TunnelCreationInformation, TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { Disposable } from 'vs/base/common/lifecycle';
import type { TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver';
......@@ -57,8 +57,8 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
async $setTunnelProvider(): Promise<void> {
const tunnelProvider: ITunnelProvider = {
forwardPort: (tunnelOptions: TunnelOptions) => {
const forward = this._proxy.$forwardPort(tunnelOptions);
forwardPort: (tunnelOptions: TunnelOptions, tunnelCreationInformation: TunnelCreationInformation) => {
const forward = this._proxy.$forwardPort(tunnelOptions, tunnelCreationInformation);
if (forward) {
return forward.then(tunnel => {
return {
......
......@@ -47,7 +47,7 @@ import * as search from 'vs/workbench/services/search/common/search';
import { EditorGroupColumn, SaveReason } from 'vs/workbench/common/editor';
import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator';
import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
import { TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { TunnelCreationInformation, TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor, InternalTimelineOptions } from 'vs/workbench/contrib/timeline/common/timeline';
import { revive } from 'vs/base/common/marshalling';
import { IProcessedOutput, INotebookDisplayOrder, NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEventDto, NotebookDataDto, IMainCellDto, INotebookDocumentFilter, INotebookKernelInfoDto2, TransientMetadata, INotebookCellStatusBarEntry, ICellRange, INotebookDecorationRenderOptions, INotebookExclusiveDocumentFilter } from 'vs/workbench/contrib/notebook/common/notebookCommon';
......@@ -1742,7 +1742,7 @@ export interface MainThreadThemingShape extends IDisposable {
}
export interface ExtHostTunnelServiceShape {
$forwardPort(tunnelOptions: TunnelOptions): Promise<TunnelDto> | undefined;
$forwardPort(tunnelOptions: TunnelOptions, tunnelCreationInformation: TunnelCreationInformation): Promise<TunnelDto> | undefined;
$closeTunnel(remote: { host: string, port: number }, silent?: boolean): Promise<void>;
$onDidTunnelsChange(): Promise<void>;
}
......
......@@ -6,7 +6,7 @@
import { ExtHostTunnelServiceShape, MainContext, MainThreadTunnelServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import * as vscode from 'vscode';
import { RemoteTunnel, TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { RemoteTunnel, TunnelCreationInformation, TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Emitter } from 'vs/base/common/event';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
......@@ -61,7 +61,7 @@ export class ExtHostTunnelService implements IExtHostTunnelService {
await this._proxy.$tunnelServiceReady();
return { dispose: () => { } };
}
$forwardPort(tunnelOptions: TunnelOptions): Promise<TunnelDto> | undefined { return undefined; }
$forwardPort(tunnelOptions: TunnelOptions, tunnelCreationInformation: TunnelCreationInformation): Promise<TunnelDto> | undefined { return undefined; }
async $closeTunnel(remote: { host: string, port: number }): Promise<void> { }
async $onDidTunnelsChange(): Promise<void> { }
}
......@@ -16,7 +16,7 @@ import { isLinux } from 'vs/base/common/platform';
import { IExtHostTunnelService, TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
import { asPromise } from 'vs/base/common/async';
import { Event, Emitter } from 'vs/base/common/event';
import { TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { TunnelOptions, TunnelCreationInformation } from 'vs/platform/remote/common/tunnel';
class ExtensionTunnel implements vscode.Tunnel {
private _onDispose: Emitter<void> = new Emitter();
......@@ -36,7 +36,7 @@ class ExtensionTunnel implements vscode.Tunnel {
export class ExtHostTunnelService extends Disposable implements IExtHostTunnelService {
readonly _serviceBrand: undefined;
private readonly _proxy: MainThreadTunnelServiceShape;
private _forwardPortProvider: ((tunnelOptions: TunnelOptions) => Thenable<vscode.Tunnel> | undefined) | undefined;
private _forwardPortProvider: ((tunnelOptions: TunnelOptions, tunnelCreationInformation: TunnelCreationInformation) => Thenable<vscode.Tunnel> | undefined) | undefined;
private _showCandidatePort: (host: string, port: number, detail: string) => Thenable<boolean> = () => { return Promise.resolve(true); };
private _extensionTunnels: Map<string, Map<number, { tunnel: vscode.Tunnel, disposeListener: IDisposable }>> = new Map();
private _onDidChangeTunnels: Emitter<void> = new Emitter<void>();
......@@ -119,9 +119,9 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
this._onDidChangeTunnels.fire();
}
$forwardPort(tunnelOptions: TunnelOptions): Promise<TunnelDto> | undefined {
$forwardPort(tunnelOptions: TunnelOptions, tunnelCreationInformation: TunnelCreationInformation): Promise<TunnelDto> | undefined {
if (this._forwardPortProvider) {
const providedPort = this._forwardPortProvider!(tunnelOptions);
const providedPort = this._forwardPortProvider(tunnelOptions, tunnelCreationInformation);
if (providedPort !== undefined) {
return asPromise(() => providedPort).then(tunnel => {
if (!this._extensionTunnels.has(tunnelOptions.remoteAddress.host)) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册