33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6- import { app , ipcMain as ipc , systemPreferences , shell , Event , contentTracing } from 'electron' ;
6+ import { app , ipcMain as ipc , systemPreferences , shell , Event , contentTracing , protocol } from 'electron' ;
77import * as platform from 'vs/base/common/platform' ;
88import { WindowsManager } from 'vs/code/electron-main/windows' ;
99import { IWindowsService , OpenContext , ActiveWindowManager } from 'vs/platform/windows/common/windows' ;
@@ -57,6 +57,7 @@ import { LogLevelSetterChannel } from 'vs/platform/log/node/logIpc';
5757import * as errors from 'vs/base/common/errors' ;
5858import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener' ;
5959import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver' ;
60+ import { connectRemoteAgentManagement } from 'vs/platform/remote/node/remoteAgentConnection' ;
6061import { IMenubarService } from 'vs/platform/menubar/common/menubar' ;
6162import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService' ;
6263import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc' ;
@@ -68,6 +69,10 @@ import { THEME_STORAGE_KEY, THEME_BG_STORAGE_KEY } from 'vs/code/electron-main/t
6869import { nativeSep , join } from 'vs/base/common/paths' ;
6970import { homedir } from 'os' ;
7071import { localize } from 'vs/nls' ;
72+ import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts' ;
73+ import { IRemoteAuthorityResolverChannel , RemoteAuthorityResolverChannelClient } from 'vs/platform/remote/node/remoteAuthorityResolverChannel' ;
74+ import { IRemoteAgentFileSystemChannel , REMOTE_FILE_SYSTEM_CHANNEL_NAME } from 'vs/platform/remote/node/remoteAgentFileSystemChannel' ;
75+ import { ResolvedAuthority } from 'vs/platform/remote/common/remoteAuthorityResolver' ;
7176import { SnapUpdateService } from 'vs/platform/update/electron-main/updateService.snap' ;
7277
7378export class CodeApplication {
@@ -165,6 +170,67 @@ export class CodeApplication {
165170 } ) ;
166171 } ) ;
167172
173+ const connectionPool : Map < string , ActiveConnection > = new Map < string , ActiveConnection > ( ) ;
174+
175+ class ActiveConnection {
176+ private _authority : string ;
177+ private _client : TPromise < Client > ;
178+ private _disposeRunner : RunOnceScheduler ;
179+
180+ constructor ( authority : string , connectionInfo : TPromise < ResolvedAuthority > ) {
181+ this . _authority = authority ;
182+ this . _client = connectionInfo . then ( ( { host, port } ) => {
183+ return connectRemoteAgentManagement ( host , port , `main` ) ;
184+ } ) ;
185+ this . _disposeRunner = new RunOnceScheduler ( ( ) => this . _dispose ( ) , 5000 ) ;
186+ }
187+
188+ private _dispose ( ) : void {
189+ this . _disposeRunner . dispose ( ) ;
190+ connectionPool . delete ( this . _authority ) ;
191+ this . _client . then ( ( connection ) => {
192+ connection . dispose ( ) ;
193+ } ) ;
194+ }
195+
196+ public getClient ( ) : TPromise < Client > {
197+ this . _disposeRunner . schedule ( ) ;
198+ return this . _client ;
199+ }
200+ }
201+
202+ protocol . registerBufferProtocol ( REMOTE_HOST_SCHEME , async ( request , callback ) => {
203+ if ( request . method !== 'GET' ) {
204+ return callback ( null ) ;
205+ }
206+ const uri = URI . parse ( request . url ) ;
207+
208+ let activeConnection : ActiveConnection = null ;
209+ if ( connectionPool . has ( uri . authority ) ) {
210+ activeConnection = connectionPool . get ( uri . authority ) ;
211+ } else {
212+ if ( this . sharedProcessClient ) {
213+ const remoteAuthorityResolverChannel = getDelayedChannel < IRemoteAuthorityResolverChannel > ( this . sharedProcessClient . then ( c => c . getChannel ( 'remoteAuthorityResolver' ) ) ) ;
214+ const remoteAuthorityResolverChannelClient = new RemoteAuthorityResolverChannelClient ( remoteAuthorityResolverChannel ) ;
215+ activeConnection = new ActiveConnection ( uri . authority , remoteAuthorityResolverChannelClient . resolveAuthority ( uri . authority ) ) ;
216+ connectionPool . set ( uri . authority , activeConnection ) ;
217+ }
218+ }
219+ try {
220+ const rawClient = await activeConnection . getClient ( ) ;
221+ if ( connectionPool . has ( uri . authority ) ) { // not disposed in the meantime
222+ const channel = rawClient . getChannel < IRemoteAgentFileSystemChannel > ( REMOTE_FILE_SYSTEM_CHANNEL_NAME ) ;
223+ const fileContents = await channel . call ( 'readFile' , [ uri . authority , uri ] ) ;
224+ callback ( Buffer . from ( fileContents ) ) ;
225+ } else {
226+ callback ( null ) ;
227+ }
228+ } catch ( err ) {
229+ errors . onUnexpectedError ( err ) ;
230+ callback ( null ) ;
231+ }
232+ } ) ;
233+
168234 let macOpenFileURIs : URI [ ] = [ ] ;
169235 let runningTimeout : any = null ;
170236 app . on ( 'open-file' , ( event : Event , path : string ) => {
0 commit comments