Vscode: WebView port mapping not working under Remote SSH

Created on 14 Jul 2020  ·  20Comments  ·  Source: microsoft/vscode




  • VSCode Version: 1.47.0, 1.48.0-insider
  • OS Version: macOS 10.15.5
  • Remote SSH: Ubuntu 18.04

Steps to Reproduce:

  1. Install vscode-R extension.
  2. Set r.sessionWatcher to true, and reload vscode.
  3. Use Remote-SSH to connect to remote Linux server (where R is installed).
  4. Install vscode-R extension to remote server.
  5. Create R terminal and an R session is started
  6. Run ?get

It starts an http server that provides the R documentation, and a VSCode
WebView should show up by the following extension code.

function showBrowser(url: string, title: string, viewer: string | boolean) {
    console.info(`[showBrowser] uri: ${url}, viewer: ${viewer}`);
    if (viewer === false) {
        env.openExternal(Uri.parse(url));
    } else {
        const port = parseInt(new URL(url).port);
        const panel = window.createWebviewPanel(
            'browser',
            title,
            {
                preserveFocus: true,
                viewColumn: ViewColumn[String(viewer)],
            },
            {
                enableScripts: true,
                retainContextWhenHidden: true,
                portMapping: [
                    {
                        extensionHostPort: port,
                        webviewPort: port,
                    },
                ],
            });
        panel.webview.html = getBrowserHtml(url);
    }
    console.info('[showBrowser] Done');
}

function getBrowserHtml(url: string) {
    return `
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    html, body {
        height: 100%;
        padding: 0;
        overflow: hidden;
    }
  </style>
</head>
<body>
    <iframe src="${url}" width="100%" height="100%" frameborder="0" />
</body>
</html>
`;
}

When viewer="Active", the WebView cannot be shown properly with the latest release and insider of VSCode. The iframe content is empty.

<iframe src="http://127.0.0.1:22784/library/base/html/get.html" width="100%" height="100%" frameborder="0">
</body>
</html>
</iframe>

However, if I run the following in R

.vsc.browser("http://127.0.0.1:22784/library/base/html/get.html", viewer = FALSE)

which basically calls showBrowser with viewer=false, then a local web browser is open by env.openExternal(Uri.parse(url)); the web page is properly shown. Only after this, I call ?get, or equivalently

.vsc.browser("http://127.0.0.1:22784/library/base/html/get.html", viewer = "Active")

The WebView could be properly shown.

I guess the port mapping of WebView via Remote SSH somehow is not working and it works with the port mapping enabled by env.openExternal(Uri.parse(url)). Everything works well if the same is done locally.

Related: https://github.com/Ikuyadeu/vscode-R/issues/380.


Does this issue occur when all extensions are disabled?: Yes

bug electron upstream-issue-linked webview

Most helpful comment

Thanks @mjbvz , not sure what can cause this, will look into it today.

All 20 comments

Any updates on this? It looks like extensions that rely on WebView port mapping are completely broken.

@mjbvz I'm testing with the latest insider on both macOS and Ubuntu

Version: 1.48.0-insider
Commit: 15ada625f20086007e2c4aa0d760234360cd648f
Date: 2020-07-30T14:46:01.621Z (1 hr ago)
Electron: 9.1.0
Chrome: 83.0.4103.122
Node.js: 12.14.1
V8: 8.3.110.13-electron.0
OS: Darwin x64 19.6.0

which seems to include your commit to fix this issue (?). But the port mapping still does not work. Am I missing something?

The WebView still does not work

image

while the vscode.openExternal works:

image

Hm, just tested this with a simple extension and R specifically and it seems to be working for me:

Screen Shot 2020-07-30 at 10 03 14 PM

What is your server version? This can be found by running code-insiders --status

Also can you try putting together a minimal example that shows it not working?

I'm currently working on Ubuntu via Remote-SSH and the latest insider does not work. Following is code-insiders --status:

➜  ~ code-insiders --status
[190429:0731/133506.897875:ERROR:edid_parser.cc(102)] Too short EDID data: manufacturer id
[190429:0731/133506.898027:ERROR:edid_parser.cc(102)] Too short EDID data: manufacturer id
[190461:0731/133506.942076:ERROR:appcenter_api.cc(52)] expecting appcenter url prefix
[190461:0731/133507.036018:ERROR:sandbox_linux.cc(374)] InitializeSandbox() called with multiple threads in process gpu-process.
[190475:0731/133507.062317:ERROR:appcenter_api.cc(52)] expecting appcenter url prefix
Version:          Code - Insiders 1.48.0-insider (15ada625f20086007e2c4aa0d760234360cd648f, 2020-07-30T14:47:02.372Z)
OS Version:       Linux x64 5.4.0-42-generic
CPUs:             Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz (8 x 3747)
Memory (System):  31.25GB (13.55GB free)
Load (avg):       1, 1, 1
VM:               0%
Screen Reader:    no
Process Argv:     --no-sandbox --unity-launch --crash-reporter-id 4dbf6963-fd26-4e66-8ece-6c1073059066
GPU Status:       2d_canvas:                  enabled
                  flash_3d:                   enabled
                  flash_stage3d:              enabled
                  flash_stage3d_baseline:     enabled
                  gpu_compositing:            enabled
                  multiple_raster_threads:    enabled_on
                  oop_rasterization:          disabled_off
                  opengl:                     enabled_on
                  protected_video_decode:     unavailable_off
                  rasterization:              disabled_software
                  skia_renderer:              enabled_on
                  video_decode:               unavailable_off
                  vulkan:                     disabled_off
                  webgl:                      enabled
                  webgl2:                     enabled

The minimal example is just like what you tried:

?get

and the WebView is blank. If this works then everything should work normally.

Maybe the fix somehow works for dev container but not for SSH?

I also tried with a dev container and it does not work either.

➜  ~ code-insiders --status                          
[216022:0731/141053.420434:ERROR:edid_parser.cc(102)] Too short EDID data: manufacturer id
[216022:0731/141053.420628:ERROR:edid_parser.cc(102)] Too short EDID data: manufacturer id
[216054:0731/141053.449849:ERROR:appcenter_api.cc(52)] expecting appcenter url prefix
[216054:0731/141053.520260:ERROR:sandbox_linux.cc(374)] InitializeSandbox() called with multiple threads in process gpu-process.
[216076:0731/141053.541967:ERROR:appcenter_api.cc(52)] expecting appcenter url prefix
Version:          Code - Insiders 1.48.0-insider (15ada625f20086007e2c4aa0d760234360cd648f, 2020-07-30T14:47:02.372Z)
OS Version:       Linux x64 5.4.0-42-generic
CPUs:             Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz (8 x 3886)
Memory (System):  31.25GB (12.40GB free)
Load (avg):       1, 2, 2
VM:               0%
Screen Reader:    no
Process Argv:     --no-sandbox --unity-launch --crash-reporter-id 4dbf6963-fd26-4e66-8ece-6c1073059066
GPU Status:       2d_canvas:                  enabled
                  flash_3d:                   enabled
                  flash_stage3d:              enabled
                  flash_stage3d_baseline:     enabled
                  gpu_compositing:            enabled
                  multiple_raster_threads:    enabled_on
                  oop_rasterization:          disabled_off
                  opengl:                     enabled_on
                  protected_video_decode:     unavailable_off
                  rasterization:              disabled_software
                  skia_renderer:              enabled_on
                  video_decode:               unavailable_off
                  vulkan:                     disabled_off
                  webgl:                      enabled
                  webgl2:                     enabled

CPU %   Mem MB     PID  Process
    0      128  202630  code-insiders main
    0       32  202634     zygote
    0       96  202660       gpu-process
    0       32  202635     zygote
    0       32  215755       window (undefined)
    0       32  202679     utility
    0       96  202781     shared-process
    0        0  216120       /bin/sh -c /bin/ps -ax -o pid=,ppid=,pcpu=,pmem=,command=
    0        0  216121         /bin/ps -ax -o pid=,ppid=,pcpu=,pmem=,command=
    0      192  212408     window (http://127.0.0.1:15957/library/base/html/get.html - test [Container rocker/r-ubuntu:20.04 (/bold_…] - Visual Studio Code - Insiders)
    0       96  212558       extensionHost
    0       32  212697         docker exec -i -u root -e VSCODE_REMOTE_CONTAINERS_SESSION=7ce5fb12-4cfa-41ce-a4c1-8fc32da3ad931596175676186 39ef1c5453efd827ad898619584556d6c7ff2d3b4547af2855d36e671655af26 /bin/sh
    0       32  212789         docker exec -i -u root -e REMOTE_CONTAINERS_SOCKETS=["/tmp/vscode-ssh-auth-fb6b21a14410e43eccf3972e1b0ce491f92c0369.sock","/root/.gnupg/S.gpg-agent"] -e REMOTE_CONTAINERS_IPC=/tmp/vscode-remote-containers-ipc-fb6b21a14410e43eccf3972e1b0ce491f92c0369.sock 39ef1c5453efd827ad898619584556d6c7ff2d3b4547af2855d36e671655af26 /root/.vscode-server-insiders/bin/15ada625f20086007e2c4aa0d760234360cd648f/node /tmp/vscode-remote-containers-server-fb6b21a14410e43eccf3972e1b0ce491f92c0369.js
    0       32  213010         docker exec -i -u root -e VSCODE_REMOTE_CONTAINERS_SESSION=7ce5fb12-4cfa-41ce-a4c1-8fc32da3ad931596175676186 39ef1c5453efd827ad898619584556d6c7ff2d3b4547af2855d36e671655af26 /root/.vscode-server-insiders/bin/15ada625f20086007e2c4aa0d760234360cd648f/node -e  ....const net = require('net'); ....process.stdin.pause(); ....const client = net.createConnection({ port: 37963 }, () => { .....client.pipe(process.stdout); .....process.stdin.pipe(client); ....}); ....client.on('close', function (hadError) { .....process.exit(hadError ? 1 : 0); ....}); ....client.on('error', function (err) { .....process.stderr.write(err && (err.stack || err.message) || String(err)); ....}); ...
    0       32  213027         docker exec -i -u root -e VSCODE_REMOTE_CONTAINERS_SESSION=7ce5fb12-4cfa-41ce-a4c1-8fc32da3ad931596175676186 39ef1c5453efd827ad898619584556d6c7ff2d3b4547af2855d36e671655af26 /root/.vscode-server-insiders/bin/15ada625f20086007e2c4aa0d760234360cd648f/node -e  ....const net = require('net'); ....process.stdin.pause(); ....const client = net.createConnection({ port: 37963 }, () => { .....client.pipe(process.stdout); .....process.stdin.pipe(client); ....}); ....client.on('close', function (hadError) { .....process.exit(hadError ? 1 : 0); ....}); ....client.on('error', function (err) { .....process.stderr.write(err && (err.stack || err.message) || String(err)); ....}); ...
    0       32  215173         electron_node settings.js settings.js 
    0       32  215277         docker exec -i -u root -w /root/.vscode-server-insiders/extensions 39ef1c5453efd827ad898619584556d6c7ff2d3b4547af2855d36e671655af26 /bin/sh -c # Watch installed extensions ...trap "exit 0" 16 ...old=`ls -A --full-time` ...counter=0 ...while [ $counter -lt 60 ] ...do ....sleep 1 ....new=`ls -A --full-time` ....if [ "$new" != "$old" ] ....then .....exit 1 ....fi ....counter=`expr $counter + 1` ...done ..
    0       64  215723     window (undefined)



Remote:           Container rocker/r-ubuntu:20.04 (/bold_…
OS Version:       Linux x64 5.4.0-42-generic
CPUs:             Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz (8 x 3785)
Memory (System):  31.25GB (12.50GB free)
VM:               0%
CPU %   Mem MB     PID  Process
    0       32      87  remote agent
    0       32    1194     extensionHost
    0        0    1392       /bin/bash
    0       64    2752       /usr/lib/R/bin/exec/R --no-save --no-restore
    0       32    1235     watcherService
    0        0    2995     /bin/sh -c /usr/bin/ps -ax -o pid=,ppid=,pcpu=,pmem=,command=
    0        0    2996       /usr/bin/ps -ax -o pid=,ppid=,pcpu=,pmem=,command=
Folder (test): 2 files
|      File types: Rprofile(1) R(1)
|      Conf files:

A minimal example is:

  1. Use Remote-SSH or Remote-Container to connect to a server with R installed.
  2. Install vscode-R extension on remote.
  3. Turn on "r.sessionWatcher" in settings and reload vscode.
  4. Run Rscript -e "install.packages('jsonlite')" in terminal
  5. Run vscode command R: Create R terminal and observes that the R: (not attached) status bar item gets a pid.
  6. Run R command ?get which should show up a WebView with a help documentation.

In both Remote-SSH and Remote-Container environments, I found that the first time I tried ?get on a fresh remote session in vscode-insider, it will work. Close the WebView and try again, it won't work anymore.

The following are more examples to test with:

  1. Install required packages
apt install -y libcurl4-openssl-dev libxml2-dev libssl-dev libssh2-1-dev libsasl2-dev libcsv-dev libfontconfig1-dev libcairo2-dev
  1. Install R packages
Rscript -e "install.packages(c('devtools', 'shiny'))"
  1. Run vscode command "R: Create R terminal" and try the following example and a WebView of interactive shiny app should show up.
shiny::runExample("01_hello")
  1. Ctrl + C to exit the blocking code above. Try again above code and it should still work but current it won't work again.
  2. Install the following package in R:
devtools::install_github("nx10/httpgd@boost-beast")
  1. Run the following R code:
httpgd::httpgd()
plot(rnorm(100))
httpgd::httpgdBrowse()
  1. A WebView should show up with a scatter plot. Currently, it is a blank page, but the following code calls vscode.openExternal and the page will be open in an external web browser and the scatter plot should show up normally.
.vsc.browser(httpgd::httpgdURL(), viewer = FALSE)

@deepak1556 The problem is the mapping from the request to the webview. In onBeforeRequest, the first request we see properly has a webcontentsid:

Screen Shot 2020-07-31 at 1 05 47 AM

Subsequent requests do not:

Screen Shot 2020-07-31 at 1 06 25 AM

I will see if I can put together a small electron reproduction.

However instead of using the web contents id at all, it would be nice if we could instead use the requesting origin:
https://github.com/electron/electron/issues/24303 (since this would also support iframe based webviews)

Filed https://github.com/electron/electron/issues/24820 to track the electron issue upstream

@deepak1556 Instead of fixing my new issue, I think we should prioritize either:

I'm wondering if there's anything that could be done on our side to walk-around this at the moment? It looks like this cannot be fixed in a short term due to upstream issue.

Is it possible that we take advantage of the mechanism behind env.openExternal(Uri.parse(url)) so that the port mapping is enabled?

Yes you should be able to workaround the issue by calling openExternal yourself. Not great but I think it should work

@deepak1556 Let me know if I can help you look into the electron issues/feature requests

Is it possible to use the port mapping enabled by openExternal or by some other port mapping API (I haven't seen any?) but not literally open an external web browser page?

@mjbvz sorry was looped into other work, I will have a fix for the mentioned electron issues tomorrow or day after.

Version: 1.49.0-insider
Commit: 6384e3246884694cbc34eacc70281ada15e2c7f2
Date: 2020-08-28T16:02:16.834Z
Electron: 9.2.1
Chrome: 83.0.4103.122
Node.js: 12.14.1
V8: 8.3.110.13-electron.0
OS: Darwin x64 17.7.0

With the latest version of VS Code Insider, WebView port mapping for LaTeX Workshop still does not work well under Remote SSH. Manually calling env.openExternal is required. After calling env.openExternal manually, everything works.

@renkun-ken How about your extension?

@tamuratak Same here, not working with

Version: 1.49.0-insider
Commit: 6384e3246884694cbc34eacc70281ada15e2c7f2
Date: 2020-08-28T16:02:16.834Z (8 hrs ago)
Electron: 9.2.1
Chrome: 83.0.4103.122
Node.js: 12.14.1
V8: 8.3.110.13-electron.0
OS: Darwin x64 19.6.0

@deepak1556 Looks like we are still hitting electron/electron#24820

The first request includes all the request details we need:

Screen Shot 2020-08-28 at 9 33 34 PM

However subsequent request only include very basic info:

Screen Shot 2020-08-28 at 9 31 55 PM

I confirmed that port mappings do work for the first request where all of the information is present

Thanks @mjbvz , not sure what can cause this, will look into it today.

@deepak1556 Pushing this to next iteration since it sounds like there are more important electron issues. Can you please look into this during debt week in October?

@mjbvz definitely, sorry for pushing this to backlog.

Thanks to auto-forwarding from terminal output which seems to partially resolve this issue.

image

Was this page helpful?
0 / 5 - 0 ratings