mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 13:46:13 +00:00
parent
f0a0c734f3
commit
a414bf2973
|
@ -382,13 +382,14 @@ async function tunnelFactory(tunnelOptions: vscode.TunnelOptions, tunnelCreation
|
|||
|
||||
return createTunnelService();
|
||||
|
||||
function newTunnel(localAddress: { host: string, port: number }) {
|
||||
function newTunnel(localAddress: { host: string, port: number }): vscode.Tunnel {
|
||||
const onDidDispose: vscode.EventEmitter<void> = new vscode.EventEmitter();
|
||||
let isDisposed = false;
|
||||
return {
|
||||
localAddress,
|
||||
remoteAddress: tunnelOptions.remoteAddress,
|
||||
public: !!vscode.workspace.getConfiguration('testresolver').get('supportPublicPorts') && tunnelOptions.public,
|
||||
protocol: tunnelOptions.protocol,
|
||||
onDidDispose: onDidDispose.event,
|
||||
dispose: () => {
|
||||
if (!isDisposed) {
|
||||
|
|
|
@ -20,6 +20,7 @@ export interface RemoteTunnel {
|
|||
readonly tunnelLocalPort?: number;
|
||||
readonly localAddress: string;
|
||||
readonly public: boolean;
|
||||
readonly protocol?: string;
|
||||
dispose(silent?: boolean): Promise<void>;
|
||||
}
|
||||
|
||||
|
@ -28,6 +29,12 @@ export interface TunnelOptions {
|
|||
localAddressPort?: number;
|
||||
label?: string;
|
||||
public?: boolean;
|
||||
protocol?: string;
|
||||
}
|
||||
|
||||
export enum TunnelProtocol {
|
||||
Http = 'http',
|
||||
Https = 'https'
|
||||
}
|
||||
|
||||
export interface TunnelCreationOptions {
|
||||
|
@ -70,6 +77,8 @@ export interface ITunnel {
|
|||
|
||||
public?: boolean;
|
||||
|
||||
protocol?: string;
|
||||
|
||||
/**
|
||||
* Implementers of Tunnel should fire onDidDispose when dispose is called.
|
||||
*/
|
||||
|
@ -90,7 +99,7 @@ export interface ITunnelService {
|
|||
readonly onAddedTunnelProvider: Event<void>;
|
||||
|
||||
canTunnel(uri: URI): boolean;
|
||||
openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded?: boolean, isPublic?: boolean): Promise<RemoteTunnel | undefined> | undefined;
|
||||
openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded?: boolean, isPublic?: boolean, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
|
||||
closeTunnel(remoteHost: string, remotePort: number): Promise<void>;
|
||||
setTunnelProvider(provider: ITunnelProvider | undefined, features: TunnelProviderFeatures): IDisposable;
|
||||
}
|
||||
|
@ -207,7 +216,7 @@ export abstract class AbstractTunnelService implements ITunnelService {
|
|||
this._tunnels.clear();
|
||||
}
|
||||
|
||||
openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded: boolean = false, isPublic: boolean = false): Promise<RemoteTunnel | undefined> | undefined {
|
||||
openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded: boolean = false, isPublic: boolean = false, protocol?: string): Promise<RemoteTunnel | undefined> | undefined {
|
||||
this.logService.trace(`ForwardedPorts: (TunnelService) openTunnel request for ${remoteHost}:${remotePort} on local port ${localPort}.`);
|
||||
if (!addressProvider) {
|
||||
return undefined;
|
||||
|
@ -217,7 +226,7 @@ export abstract class AbstractTunnelService implements ITunnelService {
|
|||
remoteHost = 'localhost';
|
||||
}
|
||||
|
||||
const resolvedTunnel = this.retainOrCreateTunnel(addressProvider, remoteHost, remotePort, localPort, elevateIfNeeded, isPublic);
|
||||
const resolvedTunnel = this.retainOrCreateTunnel(addressProvider, remoteHost, remotePort, localPort, elevateIfNeeded, isPublic, protocol);
|
||||
if (!resolvedTunnel) {
|
||||
this.logService.trace(`ForwardedPorts: (TunnelService) Tunnel was not created.`);
|
||||
return resolvedTunnel;
|
||||
|
@ -246,6 +255,7 @@ export abstract class AbstractTunnelService implements ITunnelService {
|
|||
tunnelLocalPort: tunnel.tunnelLocalPort,
|
||||
localAddress: tunnel.localAddress,
|
||||
public: tunnel.public,
|
||||
protocol: tunnel.protocol,
|
||||
dispose: async () => {
|
||||
this.logService.trace(`ForwardedPorts: (TunnelService) dispose request for ${tunnel.tunnelRemoteHost}:${tunnel.tunnelRemotePort} `);
|
||||
const existingHost = this._tunnels.get(tunnel.tunnelRemoteHost);
|
||||
|
@ -333,14 +343,14 @@ export abstract class AbstractTunnelService implements ITunnelService {
|
|||
return !!extractLocalHostUriMetaDataForPortMapping(uri);
|
||||
}
|
||||
|
||||
protected abstract retainOrCreateTunnel(addressProvider: IAddressProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, isPublic: boolean): Promise<RemoteTunnel | undefined> | undefined;
|
||||
protected abstract retainOrCreateTunnel(addressProvider: IAddressProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, isPublic: boolean, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
|
||||
|
||||
protected createWithProvider(tunnelProvider: ITunnelProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, isPublic: boolean): Promise<RemoteTunnel | undefined> | undefined {
|
||||
protected createWithProvider(tunnelProvider: ITunnelProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, isPublic: boolean, protocol?: string): Promise<RemoteTunnel | undefined> | undefined {
|
||||
this.logService.trace(`ForwardedPorts: (TunnelService) Creating tunnel with provider ${remoteHost}:${remotePort} on local port ${localPort}.`);
|
||||
|
||||
const preferredLocalPort = localPort === undefined ? remotePort : localPort;
|
||||
const creationInfo = { elevationRequired: elevateIfNeeded ? isPortPrivileged(preferredLocalPort) : false };
|
||||
const tunnelOptions: TunnelOptions = { remoteAddress: { host: remoteHost, port: remotePort }, localAddressPort: localPort, public: isPublic };
|
||||
const tunnelOptions: TunnelOptions = { remoteAddress: { host: remoteHost, port: remotePort }, localAddressPort: localPort, public: isPublic, protocol };
|
||||
const tunnel = tunnelProvider.forwardPort(tunnelOptions, creationInfo);
|
||||
this.logService.trace('ForwardedPorts: (TunnelService) Tunnel created by provider.');
|
||||
if (tunnel) {
|
||||
|
|
|
@ -148,7 +148,7 @@ export class BaseTunnelService extends AbstractTunnelService {
|
|||
return (this.configurationService.getValue('remote.localPortHost') === 'localhost') ? '127.0.0.1' : '0.0.0.0';
|
||||
}
|
||||
|
||||
protected retainOrCreateTunnel(addressProvider: IAddressProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, isPublic: boolean): Promise<RemoteTunnel | undefined> | undefined {
|
||||
protected retainOrCreateTunnel(addressProvider: IAddressProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, isPublic: boolean, protocol?: string): Promise<RemoteTunnel | undefined> | undefined {
|
||||
const existing = this.getTunnelFromMap(remoteHost, remotePort);
|
||||
if (existing) {
|
||||
++existing.refcount;
|
||||
|
@ -156,7 +156,7 @@ export class BaseTunnelService extends AbstractTunnelService {
|
|||
}
|
||||
|
||||
if (this._tunnelProvider) {
|
||||
return this.createWithProvider(this._tunnelProvider, remoteHost, remotePort, localPort, elevateIfNeeded, isPublic);
|
||||
return this.createWithProvider(this._tunnelProvider, remoteHost, remotePort, localPort, elevateIfNeeded, isPublic, protocol);
|
||||
} else {
|
||||
this.logService.trace(`ForwardedPorts: (TunnelService) Creating tunnel without provider ${remoteHost}:${remotePort} on local port ${localPort}.`);
|
||||
const options: IConnectionOptions = {
|
||||
|
|
3
src/vs/vscode.proposed.d.ts
vendored
3
src/vs/vscode.proposed.d.ts
vendored
|
@ -92,6 +92,7 @@ declare module 'vscode' {
|
|||
localAddressPort?: number;
|
||||
label?: string;
|
||||
public?: boolean;
|
||||
protocol?: string;
|
||||
}
|
||||
|
||||
export interface TunnelDescription {
|
||||
|
@ -99,6 +100,8 @@ declare module 'vscode' {
|
|||
//The complete local address(ex. localhost:1234)
|
||||
localAddress: { port: number, host: string; } | string;
|
||||
public?: boolean;
|
||||
// If protocol is not provided it is assumed to be http, regardless of the localAddress.
|
||||
protocol?: string;
|
||||
}
|
||||
|
||||
export interface Tunnel extends TunnelDescription {
|
||||
|
|
|
@ -8,7 +8,7 @@ import { MainThreadTunnelServiceShape, IExtHostContext, MainContext, ExtHostCont
|
|||
import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { CandidatePort, IRemoteExplorerService, makeAddress, PORT_AUTO_FORWARD_SETTING, PORT_AUTO_SOURCE_SETTING, PORT_AUTO_SOURCE_SETTING_OUTPUT, PORT_AUTO_SOURCE_SETTING_PROCESS } from 'vs/workbench/services/remote/common/remoteExplorerService';
|
||||
import { ITunnelProvider, ITunnelService, TunnelCreationOptions, TunnelProviderFeatures, TunnelOptions, RemoteTunnel, isPortPrivileged, ProvidedPortAttributes, PortAttributesProvider } from 'vs/platform/remote/common/tunnel';
|
||||
import { ITunnelProvider, ITunnelService, TunnelCreationOptions, TunnelProviderFeatures, TunnelOptions, RemoteTunnel, isPortPrivileged, ProvidedPortAttributes, PortAttributesProvider, TunnelProtocol } from 'vs/platform/remote/common/tunnel';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import type { TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
|
@ -159,6 +159,7 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
|
|||
localAddress: typeof tunnel.localAddress === 'string' ? tunnel.localAddress : makeAddress(tunnel.localAddress.host, tunnel.localAddress.port),
|
||||
tunnelLocalPort: typeof tunnel.localAddress !== 'string' ? tunnel.localAddress.port : undefined,
|
||||
public: tunnel.public,
|
||||
protocol: tunnel.protocol ?? TunnelProtocol.Http,
|
||||
dispose: async (silent?: boolean) => {
|
||||
this.logService.trace(`ForwardedPorts: (MainThreadTunnelService) Closing tunnel from tunnel provider: ${tunnel?.remoteAddress.host}:${tunnel?.remoteAddress.port}`);
|
||||
return this._proxy.$closeTunnel({ host: tunnel.remoteAddress.host, port: tunnel.remoteAddress.port }, silent);
|
||||
|
|
|
@ -17,11 +17,12 @@ export interface TunnelDto {
|
|||
remoteAddress: { port: number, host: string };
|
||||
localAddress: { port: number, host: string } | string;
|
||||
public: boolean;
|
||||
protocol: string | undefined;
|
||||
}
|
||||
|
||||
export namespace TunnelDto {
|
||||
export function fromApiTunnel(tunnel: vscode.Tunnel): TunnelDto {
|
||||
return { remoteAddress: tunnel.remoteAddress, localAddress: tunnel.localAddress, public: !!tunnel.public };
|
||||
return { remoteAddress: tunnel.remoteAddress, localAddress: tunnel.localAddress, public: !!tunnel.public, protocol: tunnel.protocol };
|
||||
}
|
||||
export function fromServiceTunnel(tunnel: RemoteTunnel): TunnelDto {
|
||||
return {
|
||||
|
@ -30,7 +31,8 @@ export namespace TunnelDto {
|
|||
port: tunnel.tunnelRemotePort
|
||||
},
|
||||
localAddress: tunnel.localAddress,
|
||||
public: tunnel.public
|
||||
public: tunnel.public,
|
||||
protocol: tunnel.protocol
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
|||
import { ActionRunner, IAction } from 'vs/base/common/actions';
|
||||
import { IMenuService, MenuId, MenuRegistry, ILocalizedString } from 'vs/platform/actions/common/actions';
|
||||
import { createAndFillInContextMenuActions, createAndFillInActionBarActions, createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { IRemoteExplorerService, TunnelModel, makeAddress, TunnelType, ITunnelItem, Tunnel, TUNNEL_VIEW_ID, parseAddress, CandidatePort, TunnelPrivacy, TunnelEditId, mapHasAddressLocalhostOrAllInterfaces, TunnelProtocol, Attributes } from 'vs/workbench/services/remote/common/remoteExplorerService';
|
||||
import { IRemoteExplorerService, TunnelModel, makeAddress, TunnelType, ITunnelItem, Tunnel, TUNNEL_VIEW_ID, parseAddress, CandidatePort, TunnelPrivacy, TunnelEditId, mapHasAddressLocalhostOrAllInterfaces, Attributes } from 'vs/workbench/services/remote/common/remoteExplorerService';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { InputBox, MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
|
@ -34,7 +34,7 @@ import { IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platfor
|
|||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPane';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isPortPrivileged, ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
|
||||
import { isPortPrivileged, ITunnelService, RemoteTunnel, TunnelProtocol } from 'vs/platform/remote/common/tunnel';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
@ -877,7 +877,7 @@ export class TunnelPanel extends ViewPane {
|
|||
this.tunnelTypeContext.set(item.tunnelType);
|
||||
this.tunnelCloseableContext.set(!!item.closeable);
|
||||
this.tunnelPrivacyContext.set(item.privacy);
|
||||
this.tunnelProtocolContext.set(item.protocol);
|
||||
this.tunnelProtocolContext.set(item.protocol === TunnelProtocol.Https ? TunnelProtocol.Https : TunnelProtocol.Https);
|
||||
this.portChangableContextKey.set(!!item.localPort);
|
||||
} else {
|
||||
this.tunnelTypeContext.reset();
|
||||
|
@ -1397,11 +1397,7 @@ namespace SetTunnelProtocolAction {
|
|||
const attributes: Partial<Attributes> = {
|
||||
protocol
|
||||
};
|
||||
// Remove tunnel close/forward when protocol is part of the API https://github.com/microsoft/vscode/issues/124816
|
||||
await remoteExplorerService.close({ host: arg.remoteHost, port: arg.remotePort });
|
||||
await remoteExplorerService.tunnelModel.configPortsAttributes.addAttributes(arg.remotePort, attributes);
|
||||
const isPublic = arg.privacy === TunnelPrivacy.Public;
|
||||
return remoteExplorerService.forward({ host: arg.remoteHost, port: arg.remotePort }, arg.localPort, arg.name, arg.source, isPublic, isPublic);
|
||||
return remoteExplorerService.tunnelModel.configPortsAttributes.addAttributes(arg.remotePort, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ITunnelService, TunnelOptions, RemoteTunnel, TunnelCreationOptions, ITunnel } from 'vs/platform/remote/common/tunnel';
|
||||
import { ITunnelService, TunnelOptions, RemoteTunnel, TunnelCreationOptions, ITunnel, TunnelProtocol } from 'vs/platform/remote/common/tunnel';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
@ -54,6 +54,7 @@ export class TunnelFactoryContribution extends Disposable implements IWorkbenchC
|
|||
// To make sure this doesn't happen, resolve the uri immediately.
|
||||
localAddress: await this.resolveExternalUri(localAddress),
|
||||
public: !!tunnel.public,
|
||||
protocol: tunnel.protocol ?? TunnelProtocol.Http,
|
||||
dispose: async () => { await tunnel.dispose(); }
|
||||
};
|
||||
resolve(remoteTunnel);
|
||||
|
|
|
@ -18,7 +18,7 @@ export class TunnelService extends AbstractTunnelService {
|
|||
super(logService);
|
||||
}
|
||||
|
||||
protected retainOrCreateTunnel(_addressProvider: IAddressProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, isPublic: boolean): Promise<RemoteTunnel | undefined> | undefined {
|
||||
protected retainOrCreateTunnel(_addressProvider: IAddressProvider, remoteHost: string, remotePort: number, localPort: number | undefined, elevateIfNeeded: boolean, isPublic: boolean, protocol?: string): Promise<RemoteTunnel | undefined> | undefined {
|
||||
const existing = this.getTunnelFromMap(remoteHost, remotePort);
|
||||
if (existing) {
|
||||
++existing.refcount;
|
||||
|
@ -26,7 +26,7 @@ export class TunnelService extends AbstractTunnelService {
|
|||
}
|
||||
|
||||
if (this._tunnelProvider) {
|
||||
return this.createWithProvider(this._tunnelProvider, remoteHost, remotePort, localPort, elevateIfNeeded, isPublic);
|
||||
return this.createWithProvider(this._tunnelProvider, remoteHost, remotePort, localPort, elevateIfNeeded, isPublic, protocol);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
|||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ALL_INTERFACES_ADDRESSES, isAllInterfaces, isLocalhost, ITunnelService, LOCALHOST_ADDRESSES, PortAttributesProvider, ProvidedOnAutoForward, ProvidedPortAttributes, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
|
||||
import { ALL_INTERFACES_ADDRESSES, isAllInterfaces, isLocalhost, ITunnelService, LOCALHOST_ADDRESSES, PortAttributesProvider, ProvidedOnAutoForward, ProvidedPortAttributes, RemoteTunnel, TunnelProtocol } from 'vs/platform/remote/common/tunnel';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IEditableData } from 'vs/workbench/common/views';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
@ -150,11 +150,6 @@ export enum OnPortForward {
|
|||
Ignore = 'ignore'
|
||||
}
|
||||
|
||||
export enum TunnelProtocol {
|
||||
Http = 'http',
|
||||
Https = 'https'
|
||||
}
|
||||
|
||||
export interface Attributes {
|
||||
label: string | undefined;
|
||||
onAutoForward: OnPortForward | undefined,
|
||||
|
@ -563,9 +558,12 @@ export class TunnelModel extends Disposable {
|
|||
|
||||
const key = makeAddress(remote.host, remote.port);
|
||||
this.inProgress.set(key, true);
|
||||
const tunnel = await this.tunnelService.openTunnel(addressProvider, remote.host, remote.port, localPort, (!elevateIfNeeded) ? attributes?.elevateIfNeeded : elevateIfNeeded, isPublic);
|
||||
const tunnel = await this.tunnelService.openTunnel(addressProvider, remote.host, remote.port, localPort, (!elevateIfNeeded) ? attributes?.elevateIfNeeded : elevateIfNeeded, isPublic, attributes?.protocol);
|
||||
if (tunnel && tunnel.localAddress) {
|
||||
const matchingCandidate = mapHasAddressLocalhostOrAllInterfaces<CandidatePort>(this._candidates ?? new Map(), remote.host, remote.port);
|
||||
const protocol = (tunnel.protocol ?
|
||||
((tunnel.protocol === TunnelProtocol.Https) ? TunnelProtocol.Https : TunnelProtocol.Http)
|
||||
: (attributes?.protocol ?? TunnelProtocol.Http));
|
||||
const newForward: Tunnel = {
|
||||
remoteHost: tunnel.tunnelRemoteHost,
|
||||
remotePort: tunnel.tunnelRemotePort,
|
||||
|
@ -573,7 +571,7 @@ export class TunnelModel extends Disposable {
|
|||
name: attributes?.label ?? name,
|
||||
closeable: true,
|
||||
localAddress: tunnel.localAddress,
|
||||
protocol: attributes?.protocol ?? TunnelProtocol.Http,
|
||||
protocol,
|
||||
localUri: await this.makeLocalUri(tunnel.localAddress, attributes),
|
||||
runningProcess: matchingCandidate?.detail,
|
||||
hasRunningProcess: !!matchingCandidate,
|
||||
|
@ -591,12 +589,12 @@ export class TunnelModel extends Disposable {
|
|||
return tunnel;
|
||||
}
|
||||
} else {
|
||||
if (attributes?.label ?? name) {
|
||||
existingTunnel.name = attributes?.label ?? name;
|
||||
const newName = attributes?.label ?? name;
|
||||
if (newName !== existingTunnel.name) {
|
||||
existingTunnel.name = newName;
|
||||
this._onForwardPort.fire();
|
||||
}
|
||||
// Remove tunnel provider check when protocol is part of the API https://github.com/microsoft/vscode/issues/124816
|
||||
if (!this.tunnelService.hasTunnelProvider && attributes?.protocol && (attributes.protocol !== existingTunnel.protocol)) {
|
||||
if (attributes?.protocol && (attributes.protocol !== existingTunnel.protocol)) {
|
||||
await this.close(existingTunnel.remoteHost, existingTunnel.remotePort);
|
||||
await this.forward({ host: existingTunnel.remoteHost, port: existingTunnel.remotePort }, local, name, source, elevateIfNeeded, isPublic, restore, attributes);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ interface ITunnelOptions {
|
|||
label?: string;
|
||||
|
||||
public?: boolean;
|
||||
|
||||
protocol?: string;
|
||||
}
|
||||
|
||||
export interface TunnelCreationOptions {
|
||||
|
@ -93,6 +95,11 @@ interface ITunnel {
|
|||
|
||||
public?: boolean;
|
||||
|
||||
/**
|
||||
* If protocol is not provided, it is assumed to be http, regardless of the localAddress
|
||||
*/
|
||||
protocol?: string;
|
||||
|
||||
/**
|
||||
* Implementers of Tunnel should fire onDidDispose when dispose is called.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue