@@ -20,13 +20,14 @@ import { extractAgents } from "./api-helper";
20
20
import * as cli from "./cliManager" ;
21
21
import { Commands } from "./commands" ;
22
22
import { featureSetForVersion , FeatureSet } from "./featureSet" ;
23
- import { getHeaderCommand } from "./headers" ;
23
+ import { getHeaderArgs } from "./headers" ;
24
24
import { Inbox } from "./inbox" ;
25
25
import { SSHConfig , SSHValues , mergeSSHConfigValues } from "./sshConfig" ;
26
26
import { computeSSHProperties , sshSupportsSetEnv } from "./sshSupport" ;
27
27
import { Storage } from "./storage" ;
28
28
import {
29
29
AuthorityPrefix ,
30
+ escapeCommandArg ,
30
31
expandPath ,
31
32
findPort ,
32
33
parseRemoteAuthority ,
@@ -758,34 +759,21 @@ export class Remote {
758
759
const sshConfig = new SSHConfig ( sshConfigFile ) ;
759
760
await sshConfig . load ( ) ;
760
761
761
- const escape = ( str :string ) :string => `"${ str . replace ( / " / g, '\\"' ) } "` ;
762
- // Escape a command line to be executed by the Coder binary, so ssh doesn't substitute variables.
763
- const escapeSubcommand :( str :string ) => string =
764
- os . platform ( ) === "win32"
765
- ?// On Windows variables are %VAR%, and we need to use double quotes.
766
- ( str ) => escape ( str ) . replace ( / % / g, "%%" )
767
- :// On *nix we can use single quotes to escape $VARS.
768
- // Note single quotes cannot be escaped inside single quotes.
769
- ( str ) => `'${ str . replace ( / ' / g, "'\\''" ) } '` ;
770
-
771
- // Add headers from the header command.
772
- let headerArg = "" ;
773
- const headerCommand = getHeaderCommand ( vscode . workspace . getConfiguration ( ) ) ;
774
- if ( typeof headerCommand === "string" && headerCommand . trim ( ) . length > 0 ) {
775
- headerArg = ` --header-command${ escapeSubcommand ( headerCommand ) } ` ;
776
- }
762
+ const headerArgs = getHeaderArgs ( vscode . workspace . getConfiguration ( ) ) ;
763
+ const headerArgList =
764
+ headerArgs . length > 0 ?`${ headerArgs . join ( " " ) } ` :"" ;
777
765
778
766
const hostPrefix = label
779
767
?`${ AuthorityPrefix } .${ label } --`
780
768
:`${ AuthorityPrefix } --` ;
781
769
782
770
const proxyCommand = featureSet . wildcardSSH
783
- ?`${ escape ( binaryPath ) } ${ headerArg } --global-config${ escape (
771
+ ?`${ escapeCommandArg ( binaryPath ) } ${ headerArgList } --global-config${ escapeCommandArg (
784
772
path . dirname ( this . storage . getSessionTokenPath ( label ) ) ,
785
- ) } ssh --stdio --usage-app=vscode --disable-autostart --network-info-dir${ escape ( this . storage . getNetworkInfoPath ( ) ) } ${ await this . formatLogArg ( logDir ) } --ssh-host-prefix${ hostPrefix } %h`
786
- :`${ escape ( binaryPath ) } ${ headerArg } vscodessh --network-info-dir${ escape (
773
+ ) } ssh --stdio --usage-app=vscode --disable-autostart --network-info-dir${ escapeCommandArg ( this . storage . getNetworkInfoPath ( ) ) } ${ await this . formatLogArg ( logDir ) } --ssh-host-prefix${ hostPrefix } %h`
774
+ :`${ escapeCommandArg ( binaryPath ) } ${ headerArgList } vscodessh --network-info-dir${ escapeCommandArg (
787
775
this . storage . getNetworkInfoPath ( ) ,
788
- ) } ${ await this . formatLogArg ( logDir ) } --session-token-file${ escape ( this . storage . getSessionTokenPath ( label ) ) } --url-file${ escape (
776
+ ) } ${ await this . formatLogArg ( logDir ) } --session-token-file${ escapeCommandArg ( this . storage . getSessionTokenPath ( label ) ) } --url-file${ escapeCommandArg (
789
777
this . storage . getUrlPath ( label ) ,
790
778
) } %h`;
791
779