mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-21 00:59:03 +01:00
Moving resolve uri logic into openerService
- Add a resolveExternalUri function to the opener service. This service already has to know how to resolve external uris so it makes sense that the function lives there - Move the tunneling logic for desktop into window.ts - Make result of resolve disposable
This commit is contained in:
@@ -4,28 +4,26 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { ExtHostContext, ExtHostWindowShape, IExtHostContext, MainContext, MainThreadWindowShape, IOpenUriOptions } from '../common/extHost.protocol';
|
||||
import { ITunnelService, RemoteTunnel, extractLocalHostUriMetaDataForPortMapping } from 'vs/platform/remote/common/tunnel';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { ExtHostContext, ExtHostWindowShape, IExtHostContext, IOpenUriOptions, MainContext, MainThreadWindowShape } from '../common/extHost.protocol';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadWindow)
|
||||
export class MainThreadWindow implements MainThreadWindowShape {
|
||||
|
||||
private handlePool = 1;
|
||||
|
||||
private readonly proxy: ExtHostWindowShape;
|
||||
private readonly disposables = new DisposableStore();
|
||||
private readonly _tunnels = new Map<number, { refcount: number, readonly value: Promise<RemoteTunnel> }>();
|
||||
private readonly resolved = new Map<number, IDisposable>();
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IOpenerService private readonly openerService: IOpenerService,
|
||||
@ITunnelService private readonly tunnelService: ITunnelService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
this.proxy = extHostContext.getProxy(ExtHostContext.ExtHostWindow);
|
||||
|
||||
@@ -36,10 +34,10 @@ export class MainThreadWindow implements MainThreadWindowShape {
|
||||
dispose(): void {
|
||||
this.disposables.dispose();
|
||||
|
||||
for (const { value } of this._tunnels.values()) {
|
||||
value.then(tunnel => tunnel.dispose());
|
||||
for (const value of this.resolved.values()) {
|
||||
value.dispose();
|
||||
}
|
||||
this._tunnels.clear();
|
||||
this.resolved.clear();
|
||||
}
|
||||
|
||||
$getWindowVisibility(): Promise<boolean> {
|
||||
@@ -51,61 +49,23 @@ export class MainThreadWindow implements MainThreadWindowShape {
|
||||
return this.openerService.open(uri, { openExternal: true, allowTunneling: options.allowTunneling });
|
||||
}
|
||||
|
||||
async $resolveExternalUri(uriComponents: UriComponents, options: IOpenUriOptions): Promise<UriComponents> {
|
||||
async $resolveExternalUri(uriComponents: UriComponents, options: IOpenUriOptions): Promise<{ handle: number, result: UriComponents }> {
|
||||
const uri = URI.revive(uriComponents);
|
||||
const embedderResolver = this.getEmbedderResolver();
|
||||
if (embedderResolver) {
|
||||
return embedderResolver(uri);
|
||||
}
|
||||
return this.resolveExternalUri(uri, options);
|
||||
const handle = ++this.handlePool;
|
||||
|
||||
const result = await this.openerService.resolveExternalUri(uri, options);
|
||||
this.resolved.set(handle, result);
|
||||
|
||||
return { handle, result: result.resolved };
|
||||
}
|
||||
|
||||
async $releaseResolvedExternalUri(uriComponents: UriComponents): Promise<boolean> {
|
||||
if (this.getEmbedderResolver()) {
|
||||
// Embedder handled forwarding so there's nothing for us to clean up
|
||||
async $releaseResolvedExternalUri(handle: number): Promise<boolean> {
|
||||
const entry = this.resolved.get(handle);
|
||||
if (entry) {
|
||||
entry.dispose();
|
||||
this.resolved.delete(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
const portMappingRequest = extractLocalHostUriMetaDataForPortMapping(URI.from(uriComponents));
|
||||
if (portMappingRequest) {
|
||||
const existing = this._tunnels.get(portMappingRequest.port);
|
||||
if (existing) {
|
||||
if (--existing.refcount <= 0) {
|
||||
existing.value.then(tunnel => tunnel.dispose());
|
||||
this._tunnels.delete(portMappingRequest.port);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private getEmbedderResolver(): undefined | ((uri: URI) => Promise<URI>) {
|
||||
return this.environmentService.options && this.environmentService.options.resolveExternalUri;
|
||||
}
|
||||
|
||||
private async resolveExternalUri(uri: URI, options: IOpenUriOptions): Promise<URI> {
|
||||
if (options.allowTunneling && !!this.environmentService.configuration.remoteAuthority) {
|
||||
const portMappingRequest = extractLocalHostUriMetaDataForPortMapping(uri);
|
||||
if (portMappingRequest) {
|
||||
const tunnel = await this.retainOrCreateTunnel(portMappingRequest.port);
|
||||
if (tunnel) {
|
||||
return uri.with({ authority: `127.0.0.1:${tunnel.tunnelLocalPort}` });
|
||||
}
|
||||
}
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
private retainOrCreateTunnel(remotePort: number): Promise<RemoteTunnel> | undefined {
|
||||
const existing = this._tunnels.get(remotePort);
|
||||
if (existing) {
|
||||
++existing.refcount;
|
||||
return existing.value;
|
||||
}
|
||||
const tunnel = this.tunnelService.openTunnel(remotePort);
|
||||
if (tunnel) {
|
||||
this._tunnels.set(remotePort, { refcount: 1, value: tunnel });
|
||||
}
|
||||
return tunnel;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user