Skip to content

Add delegation back to renderer process for certain webview resource reads#102442

Merged
mjbvz merged 1 commit intomicrosoft:masterfrom
mjbvz:webview-delegate-back-to-renderer
Jul 14, 2020
Merged

Add delegation back to renderer process for certain webview resource reads#102442
mjbvz merged 1 commit intomicrosoft:masterfrom
mjbvz:webview-delegate-back-to-renderer

Conversation

@mjbvz
Copy link
Collaborator

@mjbvz mjbvz commented Jul 13, 2020

Fixes #102191

Problem
Webviews used to load local resources in the renderer process. This gave them access to all of the file system providers registered for that renderer (such as untitled and git).

However, last iteration we moved the webview protocol to the main process. This works fine for file resources, but the main process cannot read fancy uris such as git: or untitled:

Fix
To fix this, I've added code that delegates resource requests for non-file uris from the main process back to the renderer process. We tried to avoid this as it adds another round trip to each request, but I don't see a better way of doing this.

This problem only effects desktop VS Code. Web VS Code uses a service worker which always reads resources through the renderer process

…eeds

Fixes microsoft#102191

**Problem**
Webviews used to load local resources in the renderer process. This gave them access to all of the file system providers registered for that renderer (such as `untitled` and `git`).

However, last iteration we moved the webview protocol to the main process. This works fine for file resources, but the main process cannot read fancy uris such as `git:` or `untitled:`

**Fix**
To fix this, I've added code that delegates resource requests for non-file uris from the main process back to the renderer process. We tried to avoid this as it adds another round trip to each request, but I don't see a better way of doing this.

This problem only effects desktop VS Code. Web VS Code uses a service worker which always reads resources through the renderer process
@mjbvz mjbvz requested review from bpasero and deepak1556 July 13, 2020 23:38
@mjbvz mjbvz self-assigned this Jul 13, 2020
@mjbvz mjbvz added this to the July 2020 milestone Jul 13, 2020
@mjbvz
Copy link
Collaborator Author

mjbvz commented Jul 13, 2020

I do not like this change so please let me know if there is a better way to read uris such as untitled or git from the main process.

@bpasero bpasero removed their request for review July 14, 2020 06:08
@bpasero
Copy link
Member

bpasero commented Jul 14, 2020

I do not have a better solution right now. The window is currently still the exclusive owner of all file service registrations. This might change in the future when we enable sandbox and move file services into some backend, but this is not happening anytime soon. And even then, this backend is likely still a different process than the main process.

I glanced at the changes but I am not an expert in that code, so I trust your implementation.

@bpasero
Copy link
Member

bpasero commented Jul 14, 2020

Some more thoughts after gym:

  • we do have the concept of asDomUri as you know which helps for remote and I wonder if this concept should be expanded so that you can always use it. the window itself would then somehow be responsible for replying to a request (not sure if https is a good idea). this would allow us to use a consistent solution for all these things where a 3rd process needs access to resources without registered file system provider
  • alternatively, maybe whenever a file system provider is registered in the renderer it should also get registered in electron-main via some remote proxy? We do have a RemoteFileSystemProvider that works via IChannel (used for vscode-remote so far only)

I somehow feel that asDomUri would be the best way forward.

@mjbvz
Copy link
Collaborator Author

mjbvz commented Jul 14, 2020

@bpasero Thanks for taking a look.

I'm not sure I understand the point about asDomUri. With the changes we made last month, webview resources are read from the main process using a custom protocol. I don't think we can have a custom protocol go directly to a window, so is the proposal to have a standard uri scheme for reading a resource from a specific window? For example: vscode-window://windowId?path=/path/to/resource?

@mjbvz mjbvz merged commit cf0094f into microsoft:master Jul 14, 2020
@mjbvz
Copy link
Collaborator Author

mjbvz commented Jul 14, 2020

I've merged this to get additional testing in insiders. We can continue iterating on finding a better solution to this

@deepak1556
Copy link
Collaborator

@mjbvz can you please expand on how this is currently handled in the web with service workers, would like to understand the problem model first, custom protocol are limited in capabilities, we might have to explore other options.

@mjbvz
Copy link
Collaborator Author

mjbvz commented Jul 14, 2020

So on desktop, we now have this flow for loading git resources:

Webview makes resource load request
-> main process protocol handler gets request and delegates to renderer
-> renderer reads file
-> main process  gets response from renderer
-> Webview gets response from main process 

On web, we instead have the following flow:

Webview makes resource load request
-> Service worker intercepts the request and delegates to renderer
-> Renderer reads file
-> Service worker gets response from renderer
-> Webview gets response from service worker

It's the same number of hops in both cases, but the webview -> service worker communication should be pretty quick

@deepak1556
Copy link
Collaborator

deepak1556 commented Jul 14, 2020

Thanks Matt! the web solution is certainly elegant. Apart from the hops, the web solution doesn't pressure the main process since service worker gets a direct communication channel with the renderer. In desktop even if we push the logic to a background window that can establish a channel to the webview window, the custom protocol must still be handled by the main process.

Maybe we should really invest time getting service worker working for custom protocols. FWIW chrome-extension is a custom protocol for chrome browser and service worker works fine in it, so it is not impossible to get it working fine under custom protocols registered for electron, the mechanism is already there and the current blocker is electron/electron#20248 , let me look at it this week.

@bpasero
Copy link
Member

bpasero commented Jul 15, 2020

@mjbvz

I'm not sure I understand the point about asDomUri. With the changes we made last month, webview resources are read from the main process using a custom protocol. I don't think we can have a custom protocol go directly to a window, so is the proposal to have a standard uri scheme for reading a resource from a specific window? For example: vscode-window://windowId?path=/path/to/resource?

Yes your proposed URI is what I had in mind. As it stands, vscode-remote and e.g. git are very similar to me: only a window can (currently) resolve resources of these schemes because:

  • the remote resolver is registered and known only in the window
  • file system providers are only registered in the window

So having a consistent URI scheme that forwards requests to the window owning these seems elegant.

On the other hand, once sandbox for windows are enabled, the situation will likely look very different. It is possible that the window then is not the one to resolve these resources but some backend process that is privileged. Nevertheless, my point was that asDomUri could be a solution too and someone owning the window is the one that can resolve these URIs.

@github-actions github-actions bot locked and limited conversation to collaborators Aug 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression: Cannot preview image in git diff

3 participants