Skip to content

Commit 1ae64d1

Browse files
committed
linuxsessionmgr: special case VSCode remote session
In a Visual Studio Code remote session, we may be able to launch a browser without the `DISPLAY` environment variable set. This is because VSCode sets the `BROWSER` environment variable in remote sessions, such that it can forward requests to start a browser to the client machine. However! There are several types of remote session in VSCode, and the way they handle automatic port forwarding differs slightly. Since a very common case in GCM for launching the user browser is the ability to connect back to GCM via localhost:<port>, we only consider a subset of remote sessions to be able to launch a browser: * Remote SSH [YES] * Dev Containers [YES] * Remote Tunnel [NO] Sadly, for whatever reason, the remote connection over Microsoft Dev Tunnels does NOT automatically surface a forwarded port to localhost on the client. The forwarded port is only available via the devtunnels.ms URLs. Detecting the different types of remote session is tricky as it's not always as explicit as we'd like. All types: VSCODE_IPC_HOOK_CLI is set. Dev Containers : REMOTE_CONTAINERS is set. Remote SSH : SSH_CONNECTION is set. Remote Tunnel : absense of REMOTE_CONTAINERS and SSH_CONNECTION. Note, when starting a tunnel server from a regular SSH connection the SSH_CONNECTION variable gets inherited by the tunnel connections themselves! This means we need to also check for the absence of SSH_TTY because the tunnel server unsets this. SSH_TTY is set only in regular SSH sessions. Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
1 parent 04b949a commit 1ae64d1

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

src/shared/Core/Interop/Linux/LinuxSessionManager.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,53 @@ private bool GetWebBrowserAvailable()
9595
return true;
9696
}
9797

98+
//
99+
// We may also be able to launch a browser if we're inside a Visual Studio Code remote session.
100+
// VSCode overrides the BROWSER environment variable to a script that allows the user to open
101+
// the browser on their client machine.
102+
//
103+
// Even though we can start a browser, one piece of critical functionality we need is the ability
104+
// to have that browser be able to connect back to GCM over localhost. There are several types
105+
// of VSCode remote session, and only some of them automatically forward ports in such a way that
106+
// the client browser can automatically connect back to GCM over localhost.
107+
//
108+
// * SSH [OK]
109+
// Connection over SSH to a remote machine.
110+
//
111+
// * Dev Containers [OK]
112+
// Connection to a container.
113+
//
114+
// * Dev Tunnels [Not OK - forwarded ports not accessible on the client via localhost]
115+
// Connection to a remote machine over the Internet using Microsoft Dev Tunnels.
116+
//
117+
// * WSL [Ignored - already handled above]
118+
//
119+
if (Environment.Variables.ContainsKey("VSCODE_IPC_HOOK_CLI") &&
120+
Environment.Variables.ContainsKey("BROWSER"))
121+
{
122+
// Looking for SSH_CONNECTION tells us we're connected via SSH.
123+
// HOWEVER, we may also see SSH_CONNECTION in a Dev Tunnel session if the tunnel server
124+
// process was started within an SSH session (and the SSH_CONNECTION environment variable
125+
// was inherited).
126+
// We therefore check for the absence of the SSH_TTY variable, which gets unset
127+
// in Dev Tunnel sessions but is always still set in regular SSH sessions.
128+
if (Environment.Variables.ContainsKey("SSH_CONNECTION") &&
129+
!Environment.Variables.ContainsKey("SSH_TTY"))
130+
{
131+
Trace.WriteLine("VSCode (Remote SSH) detected - browser is available.");
132+
return true;
133+
}
134+
135+
if (Environment.Variables.ContainsKey("REMOTE_CONTAINERS"))
136+
{
137+
Trace.WriteLine("VSCode (Dev Containers) detected - browser is available.");
138+
return true;
139+
}
140+
141+
Trace.WriteLine("VSCode (Remote Tunnel) detected - browser is not available.");
142+
return false;
143+
}
144+
98145
// We need a desktop session to be able to launch the browser in the general case
99146
return IsDesktopSession;
100147
}

0 commit comments

Comments
 (0)