@@ -14,12 +14,12 @@ import { extractAgents } from "./api-helper"
14
14
import * as cli from "./cliManager"
15
15
import { Commands } from "./commands"
16
16
import { featureSetForVersion , FeatureSet } from "./featureSet"
17
- import { getHeaderCommand } from "./headers"
17
+ import { getHeaderArgs } from "./headers"
18
18
import { Inbox } from "./inbox"
19
19
import { SSHConfig , SSHValues , mergeSSHConfigValues } from "./sshConfig"
20
20
import { computeSSHProperties , sshSupportsSetEnv } from "./sshSupport"
21
21
import { Storage } from "./storage"
22
- import { AuthorityPrefix , expandPath , findPort , parseRemoteAuthority } from "./util"
22
+ import { AuthorityPrefix , escapeCommandArg , expandPath , findPort , parseRemoteAuthority } from "./util"
23
23
import { WorkspaceMonitor } from "./workspaceMonitor"
24
24
25
25
export interface RemoteDetails extends vscode . Disposable {
@@ -611,32 +611,18 @@ export class Remote {
611
611
const sshConfig = new SSHConfig ( sshConfigFile )
612
612
await sshConfig . load ( )
613
613
614
- const escape = ( str :string ) :string => `"${ str . replace ( / " / g, '\\"' ) } "`
615
- // Escape a command line to be executed by the Coder binary, so ssh doesn't substitute variables.
616
- const escapeSubcommand :( str :string ) => string =
617
- os . platform ( ) === "win32"
618
- ?// On Windows variables are %VAR%, and we need to use double quotes.
619
- ( str ) => escape ( str ) . replace ( / % / g, "%%" )
620
- :// On *nix we can use single quotes to escape $VARS.
621
- // Note single quotes cannot be escaped inside single quotes.
622
- ( str ) => `'${ str . replace ( / ' / g, "'\\''" ) } '`
623
-
624
- // Add headers from the header command.
625
- let headerArg = ""
626
- const headerCommand = getHeaderCommand ( vscode . workspace . getConfiguration ( ) )
627
- if ( typeof headerCommand === "string" && headerCommand . trim ( ) . length > 0 ) {
628
- headerArg = ` --header-command${ escapeSubcommand ( headerCommand ) } `
629
- }
614
+ const headerArgs = getHeaderArgs ( vscode . workspace . getConfiguration ( ) )
615
+ const headerArgList = headerArgs . length > 0 ?`${ headerArgs . join ( " " ) } ` :""
630
616
631
617
const hostPrefix = label ?`${ AuthorityPrefix } .${ label } --` :`${ AuthorityPrefix } --`
632
618
633
619
const proxyCommand = featureSet . wildcardSSH
634
- ?`${ escape ( binaryPath ) } ${ headerArg } --global-config${ escape (
620
+ ?`${ escapeCommandArg ( binaryPath ) } ${ headerArgList } --global-config${ escapeCommandArg (
635
621
path . dirname ( this . storage . getSessionTokenPath ( label ) ) ,
636
- ) } ssh --stdio --usage-app=vscode --disable-autostart --network-info-dir${ escape ( this . storage . getNetworkInfoPath ( ) ) } ${ await this . formatLogArg ( logDir ) } --ssh-host-prefix${ hostPrefix } %h`
637
- :`${ escape ( binaryPath ) } ${ headerArg } vscodessh --network-info-dir${ escape (
622
+ ) } ssh --stdio --usage-app=vscode --disable-autostart --network-info-dir${ escapeCommandArg ( this . storage . getNetworkInfoPath ( ) ) } ${ await this . formatLogArg ( logDir ) } --ssh-host-prefix${ hostPrefix } %h`
623
+ :`${ escapeCommandArg ( binaryPath ) } ${ headerArgList } vscodessh --network-info-dir${ escapeCommandArg (
638
624
this . storage . getNetworkInfoPath ( ) ,
639
- ) } ${ await this . formatLogArg ( logDir ) } --session-token-file${ escape ( this . storage . getSessionTokenPath ( label ) ) } --url-file${ escape (
625
+ ) } ${ await this . formatLogArg ( logDir ) } --session-token-file${ escapeCommandArg ( this . storage . getSessionTokenPath ( label ) ) } --url-file${ escapeCommandArg (
640
626
this . storage . getUrlPath ( label ) ,
641
627
) } %h`
642
628