Simplify port forward parameters

This commit is contained in:
Alex Ross 2021-06-25 13:54:06 +02:00
parent b57065709d
commit 20099087a0
No known key found for this signature in database
GPG key ID: 89DDDBA66CBA7840
4 changed files with 85 additions and 28 deletions

View file

@ -97,7 +97,13 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
}
async $openTunnel(tunnelOptions: TunnelOptions, source: string): Promise<TunnelDto | undefined> {
const tunnel = await this.remoteExplorerService.forward(tunnelOptions.remoteAddress, tunnelOptions.localAddressPort, tunnelOptions.label, source, false);
const tunnel = await this.remoteExplorerService.forward({
remote: tunnelOptions.remoteAddress,
local: tunnelOptions.localAddressPort,
name: tunnelOptions.label,
source,
elevateIfNeeded: false
});
if (tunnel) {
if (!this.elevateionRetry
&& (tunnelOptions.localAddressPort !== undefined)
@ -121,7 +127,13 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
run: async () => {
this.elevateionRetry = true;
await this.remoteExplorerService.close({ host: tunnel.tunnelRemoteHost, port: tunnel.tunnelRemotePort });
await this.remoteExplorerService.forward(tunnelOptions.remoteAddress, tunnelOptions.localAddressPort, tunnelOptions.label, source, true);
await this.remoteExplorerService.forward({
remote: tunnelOptions.remoteAddress,
local: tunnelOptions.localAddressPort,
name: tunnelOptions.label,
source,
elevateIfNeeded: true
});
this.elevateionRetry = false;
}
}]);

View file

@ -380,7 +380,11 @@ class OnAutoForwardedAction extends Disposable {
label: nls.localize('remote.tunnelsView.elevationButton', "Use Port {0} as Sudo...", tunnel.tunnelRemotePort),
run: async () => {
await this.remoteExplorerService.close({ host: tunnel.tunnelRemoteHost, port: tunnel.tunnelRemotePort });
const newTunnel = await this.remoteExplorerService.forward({ host: tunnel.tunnelRemoteHost, port: tunnel.tunnelRemotePort }, tunnel.tunnelRemotePort, undefined, undefined, true, undefined, false);
const newTunnel = await this.remoteExplorerService.forward({
remote: { host: tunnel.tunnelRemoteHost, port: tunnel.tunnelRemotePort },
local: tunnel.tunnelRemotePort,
elevateIfNeeded: true
}, false);
if (!newTunnel) {
return;
}
@ -461,7 +465,7 @@ class OutputAutomaticPortForwarding extends Disposable {
if (this.privilegedOnly() && !isPortPrivileged(localUrl.port, (await this.remoteAgentService.getEnvironment())?.os)) {
return;
}
const forwarded = await this.remoteExplorerService.forward(localUrl, undefined, undefined, undefined, undefined, undefined, false, attributes ?? null);
const forwarded = await this.remoteExplorerService.forward({ remote: localUrl }, false, attributes ?? null);
if (forwarded) {
this.notifier.doAction([forwarded]);
}
@ -589,7 +593,7 @@ class ProcAutomaticPortForwarding extends Disposable {
if (portAttributes?.onAutoForward === OnPortForward.Ignore) {
continue;
}
const forwarded = await this.remoteExplorerService.forward(value, undefined, undefined, undefined, undefined, undefined, false, portAttributes ?? null);
const forwarded = await this.remoteExplorerService.forward({ remote: value }, false, portAttributes ?? null);
if (!alreadyForwarded && forwarded) {
this.autoForwarded.add(address);
} else if (forwarded) {

View file

@ -1077,7 +1077,10 @@ export namespace ForwardPortAction {
remoteExplorerService.setEditable(undefined, TunnelEditId.New, null);
let parsed: { host: string, port: number } | undefined;
if (success && (parsed = parseAddress(value))) {
remoteExplorerService.forward({ host: parsed.host, port: parsed.port }, undefined, undefined, undefined, true).then(tunnel => error(notificationService, tunnel, parsed!.host, parsed!.port));
remoteExplorerService.forward({
remote: { host: parsed.host, port: parsed.port },
elevateIfNeeded: true
}).then(tunnel => error(notificationService, tunnel, parsed!.host, parsed!.port));
}
},
validationMessage: (value) => validateInput(remoteExplorerService, value, tunnelService.canElevate),
@ -1100,7 +1103,10 @@ export namespace ForwardPortAction {
});
let parsed: { host: string, port: number } | undefined;
if (value && (parsed = parseAddress(value))) {
remoteExplorerService.forward({ host: parsed.host, port: parsed.port }, undefined, undefined, undefined, true).then(tunnel => error(notificationService, tunnel, parsed!.host, parsed!.port));
remoteExplorerService.forward({
remote: { host: parsed.host, port: parsed.port },
elevateIfNeeded: true
}).then(tunnel => error(notificationService, tunnel, parsed!.host, parsed!.port));
}
};
}
@ -1342,7 +1348,12 @@ namespace ChangeLocalPortAction {
if (success) {
await remoteExplorerService.close({ host: context.remoteHost, port: context.remotePort });
const numberValue = Number(value);
const newForward = await remoteExplorerService.forward({ host: context.remoteHost, port: context.remotePort }, numberValue, context.name, undefined, true);
const newForward = await remoteExplorerService.forward({
remote: { host: context.remoteHost, port: context.remotePort },
local: numberValue,
name: context.name,
elevateIfNeeded: true
});
if (newForward && newForward.tunnelLocalPort !== numberValue) {
notificationService.warn(nls.localize('remote.tunnel.changeLocalPortNumber', "The local port {0} is not available. Port number {1} has been used instead", value, newForward.tunnelLocalPort ?? newForward.localAddress));
}
@ -1365,7 +1376,13 @@ namespace MakePortPublicAction {
if (arg instanceof TunnelItem) {
const remoteExplorerService = accessor.get(IRemoteExplorerService);
await remoteExplorerService.close({ host: arg.remoteHost, port: arg.remotePort });
return remoteExplorerService.forward({ host: arg.remoteHost, port: arg.remotePort }, arg.localPort, arg.name, undefined, true, true);
return remoteExplorerService.forward({
remote: { host: arg.remoteHost, port: arg.remotePort },
local: arg.localPort,
name: arg.name,
elevateIfNeeded: true,
isPublic: true
});
}
};
}
@ -1380,7 +1397,13 @@ namespace MakePortPrivateAction {
if (arg instanceof TunnelItem) {
const remoteExplorerService = accessor.get(IRemoteExplorerService);
await remoteExplorerService.close({ host: arg.remoteHost, port: arg.remotePort });
return remoteExplorerService.forward({ host: arg.remoteHost, port: arg.remotePort }, arg.localPort, arg.name, undefined, true, false);
return remoteExplorerService.forward({
remote: { host: arg.remoteHost, port: arg.remotePort },
local: arg.localPort,
name: arg.name,
elevateIfNeeded: true,
isPublic: false
});
}
};
}

View file

@ -74,6 +74,15 @@ export enum TunnelEditId {
LocalPort = 3
}
interface TunnelProperties {
remote: { host: string, port: number },
local?: number,
name?: string,
source?: string,
elevateIfNeeded?: boolean,
isPublic?: boolean
}
export interface Tunnel {
remoteHost: string;
remotePort: number;
@ -504,7 +513,12 @@ export class TunnelModel extends Disposable {
this.logService.trace(`ForwardedPorts: (TunnelModel) restoring ports ${tunnels.map(tunnel => tunnel.remotePort).join(', ')}`);
for (let tunnel of tunnels) {
if (!mapHasAddressLocalhostOrAllInterfaces(this.detected, tunnel.remoteHost, tunnel.remotePort)) {
await this.forward({ host: tunnel.remoteHost, port: tunnel.remotePort }, tunnel.localPort, tunnel.name, undefined, undefined, tunnel.privacy === TunnelPrivacy.Public);
await this.forward({
remote: { host: tunnel.remoteHost, port: tunnel.remotePort },
local: tunnel.localPort,
name: tunnel.name,
isPublic: tunnel.privacy === TunnelPrivacy.Public
});
}
}
}
@ -551,11 +565,10 @@ export class TunnelModel extends Disposable {
return this.dialogService.show(Severity.Info, mismatchString);
}
async forward(remote: { host: string, port: number }, local?: number, name?: string, source?: string, elevateIfNeeded?: boolean,
isPublic?: boolean, restore: boolean = true, attributes?: Attributes | null): Promise<RemoteTunnel | void> {
const existingTunnel = mapHasAddressLocalhostOrAllInterfaces(this.forwarded, remote.host, remote.port);
attributes = attributes ?? ((attributes !== null) ? (await this.getAttributes([remote.port]))?.get(remote.port) : undefined);
const localPort = (local !== undefined) ? local : remote.port;
async forward(tunnelProperties: TunnelProperties, restore: boolean = true, attributes?: Attributes | null): Promise<RemoteTunnel | void> {
const existingTunnel = mapHasAddressLocalhostOrAllInterfaces(this.forwarded, tunnelProperties.remote.host, tunnelProperties.remote.port);
attributes = attributes ?? ((attributes !== null) ? (await this.getAttributes([tunnelProperties.remote.port]))?.get(tunnelProperties.remote.port) : undefined);
const localPort = (tunnelProperties.local !== undefined) ? tunnelProperties.local : tunnelProperties.remote.port;
if (!existingTunnel) {
const authority = this.environmentService.remoteAuthority;
@ -563,11 +576,11 @@ export class TunnelModel extends Disposable {
getAddress: async () => { return (await this.remoteAuthorityResolverService.resolveAuthority(authority)).authority; }
} : undefined;
const key = makeAddress(remote.host, remote.port);
const key = makeAddress(tunnelProperties.remote.host, tunnelProperties.remote.port);
this.inProgress.set(key, true);
const tunnel = await this.tunnelService.openTunnel(addressProvider, remote.host, remote.port, localPort, (!elevateIfNeeded) ? attributes?.elevateIfNeeded : elevateIfNeeded, isPublic, attributes?.protocol);
const tunnel = await this.tunnelService.openTunnel(addressProvider, tunnelProperties.remote.host, tunnelProperties.remote.port, localPort, (!tunnelProperties.elevateIfNeeded) ? attributes?.elevateIfNeeded : tunnelProperties.elevateIfNeeded, tunnelProperties.isPublic, attributes?.protocol);
if (tunnel && tunnel.localAddress) {
const matchingCandidate = mapHasAddressLocalhostOrAllInterfaces<CandidatePort>(this._candidates ?? new Map(), remote.host, remote.port);
const matchingCandidate = mapHasAddressLocalhostOrAllInterfaces<CandidatePort>(this._candidates ?? new Map(), tunnelProperties.remote.host, tunnelProperties.remote.port);
const protocol = (tunnel.protocol ?
((tunnel.protocol === TunnelProtocol.Https) ? TunnelProtocol.Https : TunnelProtocol.Http)
: (attributes?.protocol ?? TunnelProtocol.Http));
@ -575,7 +588,7 @@ export class TunnelModel extends Disposable {
remoteHost: tunnel.tunnelRemoteHost,
remotePort: tunnel.tunnelRemotePort,
localPort: tunnel.tunnelLocalPort,
name: attributes?.label ?? name,
name: attributes?.label ?? tunnelProperties.name,
closeable: true,
localAddress: tunnel.localAddress,
protocol,
@ -583,7 +596,7 @@ export class TunnelModel extends Disposable {
runningProcess: matchingCandidate?.detail,
hasRunningProcess: !!matchingCandidate,
pid: matchingCandidate?.pid,
source,
source: tunnelProperties.source,
privacy: this.makeTunnelPrivacy(tunnel.public),
userForwarded: restore
};
@ -596,16 +609,16 @@ export class TunnelModel extends Disposable {
return tunnel;
}
} else {
const newName = attributes?.label ?? name;
const newName = attributes?.label ?? tunnelProperties.name;
if (newName !== existingTunnel.name) {
existingTunnel.name = newName;
this._onForwardPort.fire();
}
if ((attributes?.protocol || (existingTunnel.protocol !== TunnelProtocol.Http)) && (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);
await this.forward(tunnelProperties, restore, attributes);
}
return mapHasAddressLocalhostOrAllInterfaces(this.remoteTunnels, remote.host, remote.port);
return mapHasAddressLocalhostOrAllInterfaces(this.remoteTunnels, tunnelProperties.remote.host, tunnelProperties.remote.port);
}
}
@ -740,7 +753,12 @@ export class TunnelModel extends Disposable {
for (const forwarded of tunnels) {
const attributes = allAttributes.get(forwarded.remotePort);
if ((attributes?.protocol || (forwarded.protocol !== TunnelProtocol.Http)) && (attributes?.protocol !== forwarded.protocol)) {
await this.forward({ host: forwarded.remoteHost, port: forwarded.remotePort }, forwarded.localPort, forwarded.name, forwarded.source, undefined, undefined, undefined, attributes);
await this.forward({
remote: { host: forwarded.remoteHost, port: forwarded.remotePort },
local: forwarded.localPort,
name: forwarded.name,
source: forwarded.source
}, undefined, attributes);
}
if (!attributes) {
@ -835,7 +853,7 @@ export interface IRemoteExplorerService {
onDidChangeEditable: Event<{ tunnel: ITunnelItem, editId: TunnelEditId } | undefined>;
setEditable(tunnelItem: ITunnelItem | undefined, editId: TunnelEditId, data: IEditableData | null): void;
getEditableData(tunnelItem: ITunnelItem | undefined, editId?: TunnelEditId): IEditableData | undefined;
forward(remote: { host: string, port: number }, localPort?: number, name?: string, source?: string, elevateIfNeeded?: boolean, isPublic?: boolean, restore?: boolean, attributes?: Attributes | null): Promise<RemoteTunnel | void>;
forward(tunnelProperties: TunnelProperties, restore?: boolean, attributes?: Attributes | null): Promise<RemoteTunnel | void>;
close(remote: { host: string, port: number }): Promise<void>;
setTunnelInformation(tunnelInformation: TunnelInformation | undefined): void;
setCandidateFilter(filter: ((candidates: CandidatePort[]) => Promise<CandidatePort[]>) | undefined): IDisposable;
@ -894,8 +912,8 @@ class RemoteExplorerService implements IRemoteExplorerService {
return this._tunnelModel;
}
forward(remote: { host: string, port: number }, local?: number, name?: string, source?: string, elevateIfNeeded?: boolean, isPublic?: boolean, restore?: boolean, attributes?: Attributes | null): Promise<RemoteTunnel | void> {
return this.tunnelModel.forward(remote, local, name, source, elevateIfNeeded, isPublic, restore, attributes);
forward(tunnelProperties: TunnelProperties, restore?: boolean, attributes?: Attributes | null): Promise<RemoteTunnel | void> {
return this.tunnelModel.forward(tunnelProperties, restore, attributes);
}
close(remote: { host: string, port: number }): Promise<void> {