From 25f501b0db035038162a4cf41fd1560882881548 Mon Sep 17 00:00:00 2001 From: Jean Pierre Date: Tue, 28 Feb 2023 21:48:06 -0500 Subject: [PATCH] Fix #61 --- src/authResolver.ts | 2 +- src/commands.ts | 4 +++- src/hostTreeView.ts | 4 ++-- src/remoteLocationHistory.ts | 4 ++-- src/ssh/sshDestination.ts | 14 ++++++++++++++ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/authResolver.ts b/src/authResolver.ts index cfc6626..9913811 100644 --- a/src/authResolver.ts +++ b/src/authResolver.ts @@ -93,7 +93,7 @@ export class RemoteSSHResolver implements vscode.RemoteAuthorityResolver, vscode this.logger.info(`Resolving ssh remote authority '${authority}' (attemp #${context.resolveAttempt})`); - const sshDest = SSHDestination.parse(dest); + const sshDest = SSHDestination.parseEncoded(dest); // It looks like default values are not loaded yet when resolving a remote, // so let's hardcode the default values here diff --git a/src/commands.ts b/src/commands.ts index a889b2f..d8eb5f1 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -3,6 +3,7 @@ import * as fs from 'fs'; import { getRemoteAuthority } from './authResolver'; import { getSSHConfigPath } from './ssh/sshConfig'; import { exists as fileExists } from './common/files'; +import SSHDestination from './ssh/sshDestination'; export async function promptOpenRemoteSSHWindow(reuseWindow: boolean) { const host = await vscode.window.showInputBox({ @@ -13,7 +14,8 @@ export async function promptOpenRemoteSSHWindow(reuseWindow: boolean) { return; } - openRemoteSSHWindow(host, reuseWindow); + const sshDest = new SSHDestination(host); + openRemoteSSHWindow(sshDest.toEncodedString(), reuseWindow); } export function openRemoteSSHWindow(host: string, reuseWindow: boolean) { diff --git a/src/hostTreeView.ts b/src/hostTreeView.ts index 608fd79..c32c344 100644 --- a/src/hostTreeView.ts +++ b/src/hostTreeView.ts @@ -95,11 +95,11 @@ export class HostTreeDataProvider extends Disposable implements vscode.TreeDataP private async openRemoteSSHWindow(element: HostItem, reuseWindow: boolean) { const sshDest = new SSHDestination(element.hostname); - openRemoteSSHWindow(sshDest.toString(), reuseWindow); + openRemoteSSHWindow(sshDest.toEncodedString(), reuseWindow); } private async openRemoteSSHLocationWindow(element: HostLocationItem, reuseWindow: boolean) { const sshDest = new SSHDestination(element.hostname); - openRemoteSSHLocationWindow(sshDest.toString(), element.path, reuseWindow); + openRemoteSSHLocationWindow(sshDest.toEncodedString(), element.path, reuseWindow); } } diff --git a/src/remoteLocationHistory.ts b/src/remoteLocationHistory.ts index 00ff82d..9393094 100644 --- a/src/remoteLocationHistory.ts +++ b/src/remoteLocationHistory.ts @@ -39,14 +39,14 @@ export function getRemoteWorkspaceLocationData(): [string, string] | undefined { let location = vscode.workspace.workspaceFile; if (location && location.scheme === 'vscode-remote' && location.authority.startsWith(REMOTE_SSH_AUTHORITY) && location.path.endsWith('.code-workspace')) { const [, host] = location.authority.split('+'); - const sshDest = SSHDestination.parse(host); + const sshDest = SSHDestination.parseEncoded(host); return [sshDest.hostname, location.path]; } location = vscode.workspace.workspaceFolders?.[0].uri; if (location && location.scheme === 'vscode-remote' && location.authority.startsWith(REMOTE_SSH_AUTHORITY)) { const [, host] = location.authority.split('+'); - const sshDest = SSHDestination.parse(host); + const sshDest = SSHDestination.parseEncoded(host); return [sshDest.hostname, location.path]; } diff --git a/src/ssh/sshDestination.ts b/src/ssh/sshDestination.ts index d4feca7..57a65aa 100644 --- a/src/ssh/sshDestination.ts +++ b/src/ssh/sshDestination.ts @@ -36,4 +36,18 @@ export default class SSHDestination { } return result; } + + // vscode.uri implementation lowercases the authority, so when reopen or restore + // a remote session from the recently openend list the connection fails + static parseEncoded(dest: string): SSHDestination { + return SSHDestination.parse(dest.replace(/\\x([0-9a-f]{2})/g, (_, charCode) => String.fromCharCode(parseInt(charCode, 16)))); + } + + toEncodedString(): string { + let result = this.toString(); + if (result.toLowerCase() !== result) { + return result.replace(/[A-Z]/g, (ch) => `\\x${ch.charCodeAt(0).toString(16).toLowerCase()}`); + } + return result; + } }