4
4
* Copyright (c) Microsoft Corporation. All rights reserved.
5
5
* Licensed under the MIT License. See License.txt in the project root for license information.
6
6
*--------------------------------------------------------------------------------------------*/
7
+ Object . defineProperty ( exports , '__esModule' , { value : true } ) ;
7
8
8
9
// @ts -check
9
10
@@ -43,13 +44,14 @@ const WEB_PLAYGROUND_VERSION = '0.0.12';
43
44
44
45
const args = minimist ( process . argv , {
45
46
boolean : [
46
- 'no- launch' ,
47
+ 'launch' ,
47
48
'help' ,
48
49
'verbose' ,
49
50
'wrap-iframe' ,
50
51
'enable-sync' ,
51
52
] ,
52
53
string : [
54
+ 'server' ,
53
55
'scheme' ,
54
56
'host' ,
55
57
'remote-authority' ,
@@ -64,7 +66,7 @@ const args = minimist(process.argv, {
64
66
if ( args . help ) {
65
67
console . log (
66
68
'yarn web [options]\n' +
67
- ' --no- launch Do not open VSCode web in the browser\n' +
69
+ ' --launch Open VSCode web in the browser\n' +
68
70
' --wrap-iframe Wrap the Web Worker Extension Host in an iframe\n' +
69
71
' --enable-sync Enable sync by default\n' +
70
72
' --scheme Protocol (https or http)\n' +
@@ -90,9 +92,6 @@ const SECONDARY_PORT = args['secondary-port'] || (parseInt(PORT, 10) + 1);
90
92
const SCHEME = args . scheme || process . env . VSCODE_SCHEME || 'http' ;
91
93
const HOST = args . host || 'localhost' ;
92
94
const AUTHORITY = process . env . VSCODE_AUTHORITY || `${ HOST } :${ PORT } ` ;
93
- const REMOTE_AUTHORITY = args [ 'remote-authority' ] || `${ HOST } :${ ( parseInt ( PORT , 10 ) + 2 ) } ` ;
94
- // TODO: config
95
- const USER_DATA_PATH = '/Users/teffen/.local/share/code-server' ;
96
95
97
96
const exists = ( path ) => util . promisify ( fs . exists ) ( path ) ;
98
97
const readFile = ( path ) => util . promisify ( fs . readFile ) ( path ) ;
@@ -228,8 +227,10 @@ const mapCallbackUriToRequestId = new Map();
228
227
/**
229
228
* @param req {http.IncomingMessage}
230
229
* @param res {http.ServerResponse}
230
+ * @param webConfigJSON {import('../../src/vs/workbench/workbench.web.api').IServerWorkbenchConstructionOptions}
231
+ * @param webConfigJSON undefined
231
232
*/
232
- const requestHandler = ( req , res ) => {
233
+ const requestHandler = ( req , res , webConfigJSON ) => {
233
234
const parsedUrl = url . parse ( req . url , true ) ;
234
235
const pathname = parsedUrl . pathname ;
235
236
@@ -260,6 +261,9 @@ const requestHandler = (req, res) => {
260
261
return handleExtension ( req , res , parsedUrl ) ;
261
262
}
262
263
if ( pathname === '/' ) {
264
+ if ( args . server ) {
265
+ return handleRootFromServer ( req , res , webConfigJSON ) ;
266
+ }
263
267
// main web
264
268
return handleRoot ( req , res ) ;
265
269
} else if ( pathname === '/callback' ) {
@@ -281,26 +285,28 @@ const requestHandler = (req, res) => {
281
285
}
282
286
} ;
283
287
284
- const server = http . createServer ( requestHandler ) ;
285
- server . listen ( LOCAL_PORT , ( ) => {
286
- if ( LOCAL_PORT !== PORT ) {
287
- console . log ( `Operating location at http://0.0.0.0:${ LOCAL_PORT } ` ) ;
288
- }
289
- console . log ( `Web UI available at ${ SCHEME } ://${ AUTHORITY } ` ) ;
290
- } ) ;
291
- server . on ( 'error' , err => {
292
- console . error ( `Error occurred in server:` ) ;
293
- console . error ( err ) ;
294
- } ) ;
288
+ if ( ! args . server ) {
289
+ const server = http . createServer ( requestHandler ) ;
290
+ server . listen ( LOCAL_PORT , ( ) => {
291
+ if ( LOCAL_PORT !== PORT ) {
292
+ console . log ( `Operating location at http://0.0.0.0:${ LOCAL_PORT } ` ) ;
293
+ }
294
+ console . log ( `Web UI available at ${ SCHEME } ://${ AUTHORITY } ` ) ;
295
+ } ) ;
296
+ server . on ( 'error' , err => {
297
+ console . error ( `Error occurred in server:` ) ;
298
+ console . error ( err ) ;
299
+ } ) ;
295
300
296
- const secondaryServer = http . createServer ( requestHandler ) ;
297
- secondaryServer . listen ( SECONDARY_PORT , ( ) => {
298
- console . log ( `Secondary server available at ${ SCHEME } ://${ HOST } :${ SECONDARY_PORT } ` ) ;
299
- } ) ;
300
- secondaryServer . on ( 'error' , err => {
301
- console . error ( `Error occurred in server:` ) ;
302
- console . error ( err ) ;
303
- } ) ;
301
+ const secondaryServer = http . createServer ( requestHandler ) ;
302
+ secondaryServer . listen ( SECONDARY_PORT , ( ) => {
303
+ console . log ( `Secondary server available at ${ SCHEME } ://${ HOST } :${ SECONDARY_PORT } ` ) ;
304
+ } ) ;
305
+ secondaryServer . on ( 'error' , err => {
306
+ console . error ( `Error occurred in server:` ) ;
307
+ console . error ( err ) ;
308
+ } ) ;
309
+ }
304
310
305
311
/**
306
312
* @param {import('http').IncomingMessage } req
@@ -403,12 +409,6 @@ async function handleRoot(req, res) {
403
409
}
404
410
}
405
411
406
- folderUri = {
407
- scheme : 'vscode-remote' ,
408
- authority : REMOTE_AUTHORITY ,
409
- path : '/Users/teffen/Projects/testing/'
410
- } ;
411
-
412
412
const { extensions : builtInExtensions } = await builtInExtensionsPromise ;
413
413
const { extensions : additionalBuiltinExtensions , locations : staticLocations } = await commandlineProvidedExtensionsPromise ;
414
414
@@ -434,15 +434,9 @@ async function handleRoot(req, res) {
434
434
: `${ HOST } :${ SECONDARY_PORT } `
435
435
) ;
436
436
437
- console . log ( '>>>' , REMOTE_AUTHORITY ) ;
438
-
439
437
const webConfigJSON = {
440
438
folderUri : folderUri ,
441
- remoteAuthority : REMOTE_AUTHORITY ,
442
439
additionalBuiltinExtensions,
443
- workspaceProvider : {
444
- payload : [ [ 'userDataPath' , USER_DATA_PATH ] ]
445
- } ,
446
440
webWorkerExtensionHostIframeSrc : `${ SCHEME } ://${ secondaryHost } /static/out/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html`
447
441
} ;
448
442
if ( args [ 'wrap-iframe' ] ) {
@@ -474,6 +468,52 @@ async function handleRoot(req, res) {
474
468
return res . end ( data ) ;
475
469
}
476
470
471
+ /**
472
+ * @param {import('http').IncomingMessage } req
473
+ * @param {import('http').ServerResponse } res
474
+ * @param webConfigJSON {import('../../src/vs/workbench/workbench.web.api').IServerWorkbenchConstructionOptions}
475
+ */
476
+ async function handleRootFromServer ( req , res , webConfigJSON ) {
477
+ const { extensions : builtInExtensions } = await builtInExtensionsPromise ;
478
+ const { extensions : additionalBuiltinExtensions , locations : staticLocations } = await commandlineProvidedExtensionsPromise ;
479
+
480
+ const dedupedBuiltInExtensions = [ ] ;
481
+ for ( const builtInExtension of builtInExtensions ) {
482
+ const extensionId = `${ builtInExtension . packageJSON . publisher } .${ builtInExtension . packageJSON . name } ` ;
483
+ if ( staticLocations [ extensionId ] ) {
484
+ fancyLog ( `${ ansiColors . magenta ( 'BuiltIn extensions' ) } : Ignoring built-in ${ extensionId } because it was overridden via --extension argument` ) ;
485
+ continue ;
486
+ }
487
+
488
+ dedupedBuiltInExtensions . push ( builtInExtension ) ;
489
+ }
490
+
491
+ if ( args . verbose ) {
492
+ fancyLog ( `${ ansiColors . magenta ( 'BuiltIn extensions' ) } : ${ dedupedBuiltInExtensions . map ( e => path . basename ( e . extensionPath ) ) . join ( ', ' ) } ` ) ;
493
+ fancyLog ( `${ ansiColors . magenta ( 'Additional extensions' ) } : ${ additionalBuiltinExtensions . map ( e => path . basename ( e . extensionLocation . path ) ) . join ( ', ' ) || 'None' } ` ) ;
494
+ }
495
+
496
+ if ( req . headers [ 'x-forwarded-host' ] ) {
497
+ // support for running in codespace => no iframe wrapping
498
+ delete webConfigJSON . webWorkerExtensionHostIframeSrc ;
499
+ }
500
+ const authSessionInfo = undefined ;
501
+
502
+ const data = ( await readFile ( WEB_MAIN ) ) . toString ( )
503
+ . replace ( '{{WORKBENCH_WEB_CONFIGURATION}}' , ( ) => escapeAttribute ( JSON . stringify ( webConfigJSON ) ) ) // use a replace function to avoid that regexp replace patterns ($&, $0, ...) are applied
504
+ . replace ( '{{WORKBENCH_BUILTIN_EXTENSIONS}}' , ( ) => escapeAttribute ( JSON . stringify ( dedupedBuiltInExtensions ) ) )
505
+ . replace ( '{{WORKBENCH_AUTH_SESSION}}' , ( ) => authSessionInfo ? escapeAttribute ( JSON . stringify ( authSessionInfo ) ) : '' )
506
+ . replace ( '{{WEBVIEW_ENDPOINT}}' , '' ) ;
507
+
508
+ const headers = {
509
+ 'Content-Type' : 'text/html' ,
510
+ 'Content-Security-Policy' : 'require-trusted-types-for \'script\';'
511
+ } ;
512
+
513
+ res . writeHead ( 200 , headers ) ;
514
+ return res . end ( data ) ;
515
+ }
516
+
477
517
/**
478
518
* Handle HTTP requests for /callback
479
519
* @param {import('http').IncomingMessage } req
@@ -675,3 +715,5 @@ async function serveFile(req, res, filePath, responseHeaders = Object.create(nul
675
715
if ( args . launch !== false ) {
676
716
opn ( `${ SCHEME } ://${ HOST } :${ PORT } ` ) ;
677
717
}
718
+
719
+ exports . requestHandler = requestHandler ;
0 commit comments