@@ -7,7 +7,6 @@ import * as crypto from 'crypto';
7
7
import * as fs from 'fs' ;
8
8
import * as http from 'http' ;
9
9
import * as net from 'net' ;
10
- import * as os from 'os' ;
11
10
import * as path from 'path' ;
12
11
import * as url from 'url' ;
13
12
import { RunOnceScheduler } from 'vs/base/common/async' ;
@@ -33,9 +32,7 @@ import { ConfigurationService } from 'vs/platform/configuration/common/configura
33
32
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc' ;
34
33
import { IDownloadService } from 'vs/platform/download/common/download' ;
35
34
import { DownloadService } from 'vs/platform/download/common/downloadService' ;
36
- import { NativeParsedArgs } from 'vs/platform/environment/common/argv' ;
37
35
import { IEnvironmentService , INativeEnvironmentService } from 'vs/platform/environment/common/environment' ;
38
- import { OptionDescriptions , OPTIONS , parseArgs } from 'vs/platform/environment/node/argv' ;
39
36
import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService' ;
40
37
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService' ;
41
38
import { IExtensionGalleryService , IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement' ;
@@ -62,6 +59,7 @@ import { RequestChannel } from 'vs/platform/request/common/requestIpc';
62
59
import { RequestService } from 'vs/platform/request/node/requestService' ;
63
60
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
64
61
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils' ;
62
+ import { args } from 'vs/server/node/args' ;
65
63
import { IFileChangeDto } from 'vs/workbench/api/common/extHost.protocol' ;
66
64
import { IExtHostReadyMessage , IExtHostSocketMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol' ;
67
65
import { Logger } from 'vs/workbench/services/extensions/common/extensionPoints' ;
@@ -73,7 +71,7 @@ import { RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/
73
71
export type IRawURITransformerFactory = ( remoteAuthority : string ) => IRawURITransformer ;
74
72
export const IRawURITransformerFactory = createDecorator < IRawURITransformerFactory > ( 'rawURITransformerFactory' ) ;
75
73
76
- const APP_ROOT = path . join ( __dirname , '..' , '..' , '..' , '..' ) ;
74
+ export const APP_ROOT = path . join ( __dirname , '..' , '..' , '..' , '..' ) ;
77
75
const uriTransformerPath = path . join ( APP_ROOT , 'out/serverUriTransformer' ) ;
78
76
const rawURITransformerFactory : IRawURITransformerFactory = < any > require . __$__nodeRequire ( uriTransformerPath ) ;
79
77
@@ -169,7 +167,7 @@ function getMediaMime(forPath: string): string | undefined {
169
167
return mapExtToMediaMimes . get ( ext . toLowerCase ( ) ) ;
170
168
}
171
169
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 = { } ) {
173
171
try {
174
172
175
173
// Sanity checks
@@ -199,19 +197,11 @@ async function serveFile(logService: ILogService, req: http.IncomingMessage, res
199
197
}
200
198
}
201
199
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 {
203
201
res . writeHead ( errorCode , { 'Content-Type' : 'text/plain' } ) ;
204
202
res . end ( errorMessage ) ;
205
203
}
206
204
207
- interface ServerParsedArgs extends NativeParsedArgs {
208
- port ?: string
209
- }
210
- const SERVER_OPTIONS : OptionDescriptions < Required < ServerParsedArgs > > = {
211
- ...OPTIONS ,
212
- port : { type : 'string' }
213
- } ;
214
-
215
205
export interface IStartServerResult {
216
206
installingInitialExtensions ?: Promise < void >
217
207
}
@@ -227,17 +217,16 @@ export interface IServerOptions {
227
217
configureExtensionHostForkOptions ?( opts : cp . ForkOptions , accessor : ServicesAccessor , channelServer : IPCServer < RemoteAgentConnectionContext > ) : void ;
228
218
configureExtensionHostProcess ?( extensionHost : cp . ChildProcess , accessor : ServicesAccessor , channelServer : IPCServer < RemoteAgentConnectionContext > ) : IDisposable ;
229
219
220
+ verifyRequest ?( req : http . IncomingMessage , res : http . ServerResponse | undefined , accessor : ServicesAccessor ) : Promise < boolean > ;
230
221
handleRequest ?( pathname : string | null , req : http . IncomingMessage , res : http . ServerResponse , accessor : ServicesAccessor , channelServer : IPCServer < RemoteAgentConnectionContext > ) : Promise < boolean > ;
231
222
}
232
223
233
224
export async function main ( options : IServerOptions ) : Promise < void > {
234
225
const devMode = ! ! process . env [ 'VSCODE_DEV' ] ;
235
226
const connectionToken = generateUuid ( ) ;
236
227
237
- const parsedArgs = parseArgs ( process . argv , SERVER_OPTIONS ) ;
238
- parsedArgs [ 'user-data-dir' ] = URI . file ( path . join ( os . homedir ( ) , product . dataFolderName ) ) . fsPath ;
239
228
const productService = { _serviceBrand : undefined , ...product } ;
240
- const environmentService = new NativeEnvironmentService ( parsedArgs , productService ) ;
229
+ const environmentService = new NativeEnvironmentService ( args , productService ) ;
241
230
242
231
// see src/vs/code/electron-main/main.ts#142
243
232
const bufferLogService = new BufferLogService ( ) ;
@@ -571,10 +560,12 @@ export async function main(options: IServerOptions): Promise<void> {
571
560
const parsedUrl = url . parse ( req . url , true ) ;
572
561
const pathname = parsedUrl . pathname ;
573
562
563
+ if ( options . verifyRequest && ! await instantiationService . invokeFunction ( accessor => options . verifyRequest ! ( req , res , accessor ) ) ) {
564
+ return ;
565
+ }
574
566
if ( options . handleRequest && await instantiationService . invokeFunction ( accessor => options . handleRequest ! ( pathname , req , res , accessor , channelServer ) ) ) {
575
567
return ;
576
568
}
577
-
578
569
//#region headless
579
570
if ( pathname === '/vscode-remote-resource' ) {
580
571
const filePath = parsedUrl . query [ 'path' ] ;
@@ -621,12 +612,16 @@ export async function main(options: IServerOptions): Promise<void> {
621
612
}
622
613
} ) ;
623
614
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 ) => {
625
616
if ( req . headers [ 'upgrade' ] !== 'websocket' || ! req . url ) {
626
617
logService . error ( `failed to upgrade for header "${ req . headers [ 'upgrade' ] } " and url: "${ req . url } ".` ) ;
627
618
socket . end ( 'HTTP/1.1 400 Bad Request' ) ;
628
619
return ;
629
620
}
621
+ if ( options . verifyRequest && ! await instantiationService . invokeFunction ( accessor => options . verifyRequest ! ( req , undefined , accessor ) ) ) {
622
+ socket . end ( 'HTTP/1.1 401 Unauthorized' ) ;
623
+ return ;
624
+ }
630
625
const { query } = url . parse ( req . url , true ) ;
631
626
// /?reconnectionToken=c0e3a8af-6838-44fb-851b-675401030831&reconnection=false&skipWebSocketFrames=false
632
627
const reconnection = 'reconnection' in query && query [ 'reconnection' ] === 'true' ;
@@ -736,7 +731,7 @@ export async function main(options: IServerOptions): Promise<void> {
736
731
logService . info ( `[${ token } ] Management connection is connected.` ) ;
737
732
} else {
738
733
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.` ) ;
740
735
protocol . sendControl ( VSBuffer . fromString ( JSON . stringify ( { type : 'error' , reason : 'Management connection is not running.' } as ErrorMessage ) ) ) ;
741
736
safeDisposeProtocolAndSocket ( protocol ) ;
742
737
return ;
@@ -826,17 +821,17 @@ export async function main(options: IServerOptions): Promise<void> {
826
821
socket . end ( ) ;
827
822
extensionHost . kill ( ) ;
828
823
client . extensionHost = undefined ;
829
- logService . info ( `[${ token } ] Extension host is disconnected.` ) ;
824
+ logService . info ( `[${ token } ] Extension host is disconnected.` ) ;
830
825
}
831
826
832
827
extensionHost . on ( 'error' , err => {
833
828
dispose ( ) ;
834
- logService . error ( `[${ token } ] Extension host failed with: ` , err ) ;
829
+ logService . error ( `[${ token } ] Extension host failed with: ` , err ) ;
835
830
} ) ;
836
831
extensionHost . on ( 'exit' , ( code : number , signal : string ) => {
837
832
dispose ( ) ;
838
833
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 } .` ) ;
840
835
}
841
836
} ) ;
842
837
@@ -851,7 +846,7 @@ export async function main(options: IServerOptions): Promise<void> {
851
846
permessageDeflate,
852
847
inflateBytes
853
848
} as IExtHostSocketMessage , socket ) ;
854
- logService . info ( `[${ token } ] Extension host is connected.` ) ;
849
+ logService . info ( `[${ token } ] Extension host is connected.` ) ;
855
850
}
856
851
} ;
857
852
extensionHost . on ( 'message' , readyListener ) ;
@@ -860,13 +855,13 @@ export async function main(options: IServerOptions): Promise<void> {
860
855
toDispose = instantiationService . invokeFunction ( accessor => options . configureExtensionHostProcess ! ( extensionHost , accessor , channelServer ) ) ;
861
856
}
862
857
client . extensionHost = extensionHost ;
863
- logService . info ( `[${ token } ] Extension host is started.` ) ;
858
+ logService . info ( `[${ token } ] Extension host is started.` ) ;
864
859
} 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 ) ;
866
861
}
867
862
} else {
868
863
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.` ) ;
870
865
protocol . sendControl ( VSBuffer . fromString ( JSON . stringify ( { type : 'error' , reason : 'Extension host is not running.' } as ErrorMessage ) ) ) ;
871
866
safeDisposeProtocolAndSocket ( protocol ) ;
872
867
return ;
@@ -886,7 +881,7 @@ export async function main(options: IServerOptions): Promise<void> {
886
881
permessageDeflate,
887
882
inflateBytes
888
883
} as IExtHostSocketMessage , socket ) ;
889
- logService . info ( `[${ token } ] Extension host is reconnected.` ) ;
884
+ logService . info ( `[${ token } ] Extension host is reconnected.` ) ;
890
885
}
891
886
} else {
892
887
logService . error ( `[${ token } ] Unexpected connection type:` , msg . desiredConnectionType ) ;
@@ -899,8 +894,8 @@ export async function main(options: IServerOptions): Promise<void> {
899
894
} ) ;
900
895
} ) ;
901
896
let port = 3000 ;
902
- if ( parsedArgs . port ) {
903
- port = Number ( parsedArgs . port ) ;
897
+ if ( args . port ) {
898
+ port = Number ( args . port ) ;
904
899
} else if ( typeof options . port === 'number' ) {
905
900
port = options . port ;
906
901
}
0 commit comments