@@ -7,7 +7,6 @@ import * as crypto from 'crypto';
77import * as fs from 'fs' ;
88import * as http from 'http' ;
99import * as net from 'net' ;
10- import * as os from 'os' ;
1110import * as path from 'path' ;
1211import * as url from 'url' ;
1312import { RunOnceScheduler } from 'vs/base/common/async' ;
@@ -33,9 +32,7 @@ import { ConfigurationService } from 'vs/platform/configuration/common/configura
3332import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc' ;
3433import { IDownloadService } from 'vs/platform/download/common/download' ;
3534import { DownloadService } from 'vs/platform/download/common/downloadService' ;
36- import { NativeParsedArgs } from 'vs/platform/environment/common/argv' ;
3735import { IEnvironmentService , INativeEnvironmentService } from 'vs/platform/environment/common/environment' ;
38- import { OptionDescriptions , OPTIONS , parseArgs } from 'vs/platform/environment/node/argv' ;
3936import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService' ;
4037import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService' ;
4138import { IExtensionGalleryService , IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement' ;
@@ -62,6 +59,7 @@ import { RequestChannel } from 'vs/platform/request/common/requestIpc';
6259import { RequestService } from 'vs/platform/request/node/requestService' ;
6360import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
6461import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils' ;
62+ import { args } from 'vs/server/node/args' ;
6563import { IFileChangeDto } from 'vs/workbench/api/common/extHost.protocol' ;
6664import { IExtHostReadyMessage , IExtHostSocketMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol' ;
6765import { Logger } from 'vs/workbench/services/extensions/common/extensionPoints' ;
@@ -73,7 +71,7 @@ import { RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/
7371export type IRawURITransformerFactory = ( remoteAuthority : string ) => IRawURITransformer ;
7472export const IRawURITransformerFactory = createDecorator < IRawURITransformerFactory > ( 'rawURITransformerFactory' ) ;
7573
76- const APP_ROOT = path . join ( __dirname , '..' , '..' , '..' , '..' ) ;
74+ export const APP_ROOT = path . join ( __dirname , '..' , '..' , '..' , '..' ) ;
7775const uriTransformerPath = path . join ( APP_ROOT , 'out/serverUriTransformer' ) ;
7876const rawURITransformerFactory : IRawURITransformerFactory = < any > require . __$__nodeRequire ( uriTransformerPath ) ;
7977
@@ -169,7 +167,7 @@ function getMediaMime(forPath: string): string | undefined {
169167 return mapExtToMediaMimes . get ( ext . toLowerCase ( ) ) ;
170168}
171169
172- async function serveFile ( logService : ILogService , req : http . IncomingMessage , res : http . ServerResponse , filePath : string , responseHeaders : http . OutgoingHttpHeaders = { } ) {
170+ export async function serveFile ( logService : ILogService , req : http . IncomingMessage , res : http . ServerResponse , filePath : string , responseHeaders : http . OutgoingHttpHeaders = { } ) {
173171 try {
174172
175173 // Sanity checks
@@ -199,19 +197,11 @@ async function serveFile(logService: ILogService, req: http.IncomingMessage, res
199197 }
200198}
201199
202- function serveError ( req : http . IncomingMessage , res : http . ServerResponse , errorCode : number , errorMessage : string ) : void {
200+ export function serveError ( req : http . IncomingMessage , res : http . ServerResponse , errorCode : number , errorMessage : string ) : void {
203201 res . writeHead ( errorCode , { 'Content-Type' : 'text/plain' } ) ;
204202 res . end ( errorMessage ) ;
205203}
206204
207- interface ServerParsedArgs extends NativeParsedArgs {
208- port ?: string
209- }
210- const SERVER_OPTIONS : OptionDescriptions < Required < ServerParsedArgs > > = {
211- ...OPTIONS ,
212- port : { type : 'string' }
213- } ;
214-
215205export interface IStartServerResult {
216206 installingInitialExtensions ?: Promise < void >
217207}
@@ -227,17 +217,16 @@ export interface IServerOptions {
227217 configureExtensionHostForkOptions ?( opts : cp . ForkOptions , accessor : ServicesAccessor , channelServer : IPCServer < RemoteAgentConnectionContext > ) : void ;
228218 configureExtensionHostProcess ?( extensionHost : cp . ChildProcess , accessor : ServicesAccessor , channelServer : IPCServer < RemoteAgentConnectionContext > ) : IDisposable ;
229219
220+ verifyRequest ?( req : http . IncomingMessage , res : http . ServerResponse | undefined , accessor : ServicesAccessor ) : Promise < boolean > ;
230221 handleRequest ?( pathname : string | null , req : http . IncomingMessage , res : http . ServerResponse , accessor : ServicesAccessor , channelServer : IPCServer < RemoteAgentConnectionContext > ) : Promise < boolean > ;
231222}
232223
233224export async function main ( options : IServerOptions ) : Promise < void > {
234225 const devMode = ! ! process . env [ 'VSCODE_DEV' ] ;
235226 const connectionToken = generateUuid ( ) ;
236227
237- const parsedArgs = parseArgs ( process . argv , SERVER_OPTIONS ) ;
238- parsedArgs [ 'user-data-dir' ] = URI . file ( path . join ( os . homedir ( ) , product . dataFolderName ) ) . fsPath ;
239228 const productService = { _serviceBrand : undefined , ...product } ;
240- const environmentService = new NativeEnvironmentService ( parsedArgs , productService ) ;
229+ const environmentService = new NativeEnvironmentService ( args , productService ) ;
241230
242231 // see src/vs/code/electron-main/main.ts#142
243232 const bufferLogService = new BufferLogService ( ) ;
@@ -571,10 +560,12 @@ export async function main(options: IServerOptions): Promise<void> {
571560 const parsedUrl = url . parse ( req . url , true ) ;
572561 const pathname = parsedUrl . pathname ;
573562
563+ if ( options . verifyRequest && ! await instantiationService . invokeFunction ( accessor => options . verifyRequest ! ( req , res , accessor ) ) ) {
564+ return ;
565+ }
574566 if ( options . handleRequest && await instantiationService . invokeFunction ( accessor => options . handleRequest ! ( pathname , req , res , accessor , channelServer ) ) ) {
575567 return ;
576568 }
577-
578569 //#region headless
579570 if ( pathname === '/vscode-remote-resource' ) {
580571 const filePath = parsedUrl . query [ 'path' ] ;
@@ -621,12 +612,16 @@ export async function main(options: IServerOptions): Promise<void> {
621612 }
622613 } ) ;
623614 server . on ( 'error' , e => logService . error ( e ) ) ;
624- server . on ( 'upgrade' , ( req : http . IncomingMessage , socket : net . Socket ) => {
615+ server . on ( 'upgrade' , async ( req : http . IncomingMessage , socket : net . Socket ) => {
625616 if ( req . headers [ 'upgrade' ] !== 'websocket' || ! req . url ) {
626617 logService . error ( `failed to upgrade for header "${ req . headers [ 'upgrade' ] } " and url: "${ req . url } ".` ) ;
627618 socket . end ( 'HTTP/1.1 400 Bad Request' ) ;
628619 return ;
629620 }
621+ if ( options . verifyRequest && ! await instantiationService . invokeFunction ( accessor => options . verifyRequest ! ( req , undefined , accessor ) ) ) {
622+ socket . end ( 'HTTP/1.1 401 Unauthorized' ) ;
623+ return ;
624+ }
630625 const { query } = url . parse ( req . url , true ) ;
631626 // /?reconnectionToken=c0e3a8af-6838-44fb-851b-675401030831&reconnection=false&skipWebSocketFrames=false
632627 const reconnection = 'reconnection' in query && query [ 'reconnection' ] === 'true' ;
@@ -736,7 +731,7 @@ export async function main(options: IServerOptions): Promise<void> {
736731 logService . info ( `[${ token } ] Management connection is connected.` ) ;
737732 } else {
738733 if ( ! client . management ) {
739- logService . error ( `[${ token } ] Failed to reconnect: management connection is not running.` ) ;
734+ logService . error ( `[${ token } ] Failed to reconnect: management connection is not running.` ) ;
740735 protocol . sendControl ( VSBuffer . fromString ( JSON . stringify ( { type : 'error' , reason : 'Management connection is not running.' } as ErrorMessage ) ) ) ;
741736 safeDisposeProtocolAndSocket ( protocol ) ;
742737 return ;
@@ -826,17 +821,17 @@ export async function main(options: IServerOptions): Promise<void> {
826821 socket . end ( ) ;
827822 extensionHost . kill ( ) ;
828823 client . extensionHost = undefined ;
829- logService . info ( `[${ token } ] Extension host is disconnected.` ) ;
824+ logService . info ( `[${ token } ] Extension host is disconnected.` ) ;
830825 }
831826
832827 extensionHost . on ( 'error' , err => {
833828 dispose ( ) ;
834- logService . error ( `[${ token } ] Extension host failed with: ` , err ) ;
829+ logService . error ( `[${ token } ] Extension host failed with: ` , err ) ;
835830 } ) ;
836831 extensionHost . on ( 'exit' , ( code : number , signal : string ) => {
837832 dispose ( ) ;
838833 if ( code !== 0 && signal !== 'SIGTERM' ) {
839- logService . error ( `[${ token } ] Extension host exited with code: ${ code } and signal: ${ signal } .` ) ;
834+ logService . error ( `[${ token } ] Extension host exited with code: ${ code } and signal: ${ signal } .` ) ;
840835 }
841836 } ) ;
842837
@@ -851,7 +846,7 @@ export async function main(options: IServerOptions): Promise<void> {
851846 permessageDeflate,
852847 inflateBytes
853848 } as IExtHostSocketMessage , socket ) ;
854- logService . info ( `[${ token } ] Extension host is connected.` ) ;
849+ logService . info ( `[${ token } ] Extension host is connected.` ) ;
855850 }
856851 } ;
857852 extensionHost . on ( 'message' , readyListener ) ;
@@ -860,13 +855,13 @@ export async function main(options: IServerOptions): Promise<void> {
860855 toDispose = instantiationService . invokeFunction ( accessor => options . configureExtensionHostProcess ! ( extensionHost , accessor , channelServer ) ) ;
861856 }
862857 client . extensionHost = extensionHost ;
863- logService . info ( `[${ token } ] Extension host is started.` ) ;
858+ logService . info ( `[${ token } ] Extension host is started.` ) ;
864859 } catch ( e ) {
865- logService . error ( `[${ token } ] Failed to start the extension host process: ` , e ) ;
860+ logService . error ( `[${ token } ] Failed to start the extension host process: ` , e ) ;
866861 }
867862 } else {
868863 if ( ! client . extensionHost ) {
869- logService . error ( `[${ token } ] Failed to reconnect: extension host is not running.` ) ;
864+ logService . error ( `[${ token } ] Failed to reconnect: extension host is not running.` ) ;
870865 protocol . sendControl ( VSBuffer . fromString ( JSON . stringify ( { type : 'error' , reason : 'Extension host is not running.' } as ErrorMessage ) ) ) ;
871866 safeDisposeProtocolAndSocket ( protocol ) ;
872867 return ;
@@ -886,7 +881,7 @@ export async function main(options: IServerOptions): Promise<void> {
886881 permessageDeflate,
887882 inflateBytes
888883 } as IExtHostSocketMessage , socket ) ;
889- logService . info ( `[${ token } ] Extension host is reconnected.` ) ;
884+ logService . info ( `[${ token } ] Extension host is reconnected.` ) ;
890885 }
891886 } else {
892887 logService . error ( `[${ token } ] Unexpected connection type:` , msg . desiredConnectionType ) ;
@@ -899,8 +894,8 @@ export async function main(options: IServerOptions): Promise<void> {
899894 } ) ;
900895 } ) ;
901896 let port = 3000 ;
902- if ( parsedArgs . port ) {
903- port = Number ( parsedArgs . port ) ;
897+ if ( args . port ) {
898+ port = Number ( args . port ) ;
904899 } else if ( typeof options . port === 'number' ) {
905900 port = options . port ;
906901 }
0 commit comments