7
7
*
8
8
*/
9
9
10
- var fs = require ( 'fs' ) ,
10
+ const
11
+ fs = require ( 'fs' ) . promises ,
11
12
tls = require ( 'tls' ) ,
12
13
path = require ( 'path' ) ,
13
14
constants = require ( 'constants' ) ,
14
15
connected = require ( 'connected' ) ,
15
16
errs = require ( 'errs' ) ,
16
17
assign = require ( 'object-assign' ) ;
17
18
18
- var pemFormat = / - - - - - B E G I N / ;
19
+ const pemFormat = / - - - - - B E G I N / ;
19
20
20
- var CIPHERS = [
21
+ const CIPHERS = [
21
22
'ECDHE-RSA-AES256-SHA384' ,
22
23
'DHE-RSA-AES256-SHA384' ,
23
24
'ECDHE-RSA-AES256-SHA256' ,
@@ -36,7 +37,7 @@ var CIPHERS = [
36
37
'!CAMELLIA'
37
38
] . join ( ':' ) ;
38
39
39
- var secureOptions = constants . SSL_OP_NO_SSLv3 ;
40
+ const secureOptions = constants . SSL_OP_NO_SSLv3 ;
40
41
41
42
/**
42
43
* function createServers (dispatch, options, callback)
@@ -49,31 +50,28 @@ module.exports = async function createServers(options, listening) {
49
50
return listening ( err ) ;
50
51
}
51
52
52
- const [
53
- [ httpErr , http ] ,
54
- [ httpsErr , https ] ,
55
- [ http2Err , http2 ] ] = await Promise . all ( [
53
+ const [ httpResult , httpsResult , http2Result ] = await Promise . allSettled ( [
56
54
createHttp ( options . http , options . log ) ,
57
55
createHttps ( options . https , options . log ) ,
58
56
createHttps ( options . http2 , options . log , true )
59
- ] ) ;
57
+ ] )
60
58
61
59
const servers = { } ;
62
- if ( http ) servers . http = http ;
63
- if ( https ) servers . https = https ;
64
- if ( http2 ) servers . http2 = http2 ;
60
+ if ( httpResult . value ) servers . http = httpResult . value ;
61
+ if ( httpsResult . value ) servers . https = httpsResult . value ;
62
+ if ( http2Result . value ) servers . http2 = http2Result . value ;
65
63
66
- if ( httpErr || httpsErr || http2Err ) {
67
- let errorSource = http2Err || httpsErr || httpErr ;
64
+ const errorSource = httpResult . reason || httpsResult . reason || http2Result . reason ;
65
+ if ( errorSource ) {
68
66
if ( Array . isArray ( errorSource ) ) {
69
67
errorSource = errorSource [ 0 ] ;
70
68
}
71
69
return listening (
72
70
errs . create ( {
73
71
message : errorSource && errorSource . message ,
74
- http2 : http2Err ,
75
- https : httpsErr ,
76
- http : httpErr
72
+ http2 : http2Result . reason ,
73
+ https : httpsResult . reason ,
74
+ http : httpResult . reason
77
75
} ) ,
78
76
servers
79
77
) ;
@@ -172,25 +170,25 @@ function normalizeCertChainList(root, data) {
172
170
// If this is an array, treat like an array of bundles, otherwise a single
173
171
// bundle
174
172
return Array . isArray ( data )
175
- ? data . map ( function ( item ) {
173
+ ? Promise . all ( data . map ( function ( item ) {
176
174
return normalizeCertChain ( root , item ) ;
177
- } )
175
+ } ) )
178
176
: normalizePEMContent ( root , data ) ;
179
177
}
180
178
181
- function normalizeCertChain ( root , data ) {
179
+ async function normalizeCertChain ( root , data ) {
182
180
// A chain can be an array, which we concatenate together into one PEM,
183
181
// an already-concatenated chain, or a single PEM
184
182
185
- const content = normalizePEMContent ( root , data ) ;
183
+ const content = await normalizePEMContent ( root , data ) ;
186
184
return Array . isArray ( content ) ? content . join ( '\n' ) : content ;
187
185
}
188
186
189
187
function normalizeCA ( root , ca ) {
190
188
if ( ca && ! Array . isArray ( ca ) ) {
191
189
ca = [ ca ] ;
192
190
}
193
- return ca && ca . map ( normalizePEMContent . bind ( null , root ) ) ;
191
+ return ca && Promise . all ( ca . map ( normalizePEMContent . bind ( null , root ) ) ) ;
194
192
}
195
193
196
194
/**
@@ -201,9 +199,9 @@ function normalizeCA(root, ca) {
201
199
*/
202
200
function normalizePEMContent ( root , file ) {
203
201
if ( Array . isArray ( file ) )
204
- return file . map ( function map ( item ) {
202
+ return Promise . all ( file . map ( function map ( item ) {
205
203
return normalizePEMContent ( root , item ) ;
206
- } ) ;
204
+ } ) ) ;
207
205
208
206
//
209
207
// Assumption that this is a Buffer, a PEM file, or something broken
@@ -212,7 +210,7 @@ function normalizePEMContent(root, file) {
212
210
return file ;
213
211
}
214
212
215
- return fs . readFileSync ( path . resolve ( root , file ) ) ;
213
+ return fs . readFile ( path . resolve ( root , file ) ) ;
216
214
}
217
215
218
216
function normalizeCiphers ( ciphers ) {
@@ -226,11 +224,11 @@ function normalizeCiphers(ciphers) {
226
224
return ciphers ;
227
225
}
228
226
229
- function getSNIHandler ( sslOpts ) {
230
- var sniHosts = Object . keys ( sslOpts . sni ) ;
227
+ async function getSNIHandler ( sslOpts ) {
228
+ const sniHosts = Object . keys ( sslOpts . sni ) ;
231
229
232
230
// Pre-compile regexps for the hostname
233
- var hostRegexps = sniHosts . map ( function ( host ) {
231
+ const hostRegexps = sniHosts . map ( function ( host ) {
234
232
return host === '*' ? / .* / : new RegExp (
235
233
'^' +
236
234
host
@@ -242,16 +240,22 @@ function getSNIHandler(sslOpts) {
242
240
} ) ;
243
241
244
242
// Prepare secure contexts ahead-of-time
245
- var hostSecureContexts = sniHosts . map ( function ( host ) {
243
+ const hostSecureContexts = await Promise . all ( sniHosts . map ( async function ( host ) {
246
244
var hostOpts = sslOpts . sni [ host ] ;
247
245
248
246
var root = hostOpts . root || sslOpts . root ;
249
247
248
+ const [ key , cert , ca ] = await Promise . all ( [
249
+ normalizePEMContent ( root , hostOpts . key ) ,
250
+ normalizeCertContent ( root , hostOpts . cert ) ,
251
+ normalizeCA ( root , hostOpts . ca || sslOpts . ca )
252
+ ] )
253
+
250
254
return tls . createSecureContext (
251
255
assign ( { } , sslOpts , hostOpts , {
252
- key : normalizePEMContent ( root , hostOpts . key ) ,
253
- cert : normalizeCertContent ( root , hostOpts . cert ) ,
254
- ca : normalizeCA ( root , hostOpts . ca || sslOpts . ca ) ,
256
+ key,
257
+ cert,
258
+ ca,
255
259
ciphers : normalizeCiphers ( hostOpts . ciphers || sslOpts . ciphers ) ,
256
260
honorCipherOrder : ! ! (
257
261
hostOpts . honorCipherOrder || sslOpts . honorCipherOrder
@@ -260,7 +264,7 @@ function getSNIHandler(sslOpts) {
260
264
secureOptions : secureOptions
261
265
} )
262
266
) ;
263
- } ) ;
267
+ } ) ) ;
264
268
265
269
return function ( hostname , cb ) {
266
270
var matchingHostIdx = sniHosts . findIndex ( function ( candidate , i ) {
@@ -282,14 +286,14 @@ function getSNIHandler(sslOpts) {
282
286
async function createHttp ( httpConfig , log ) {
283
287
if ( typeof httpConfig === 'undefined' ) {
284
288
log ( 'http | no options.http; no server' ) ;
285
- return [ null , null ] ;
289
+ return null ;
286
290
}
287
291
288
292
if ( Array . isArray ( httpConfig ) ) {
289
293
return await createMultiple ( createHttp , httpConfig , log ) ;
290
294
}
291
295
292
- return await new Promise ( resolve => {
296
+ return await new Promise ( ( resolve , reject ) => {
293
297
var server = require ( 'http' ) . createServer ( httpConfig . handler ) ,
294
298
timeout = httpConfig . timeout ,
295
299
port = httpConfig . port ,
@@ -304,7 +308,7 @@ async function createHttp(httpConfig, log) {
304
308
305
309
log ( 'http | try listen ' + port ) ;
306
310
args . push ( function listener ( err ) {
307
- resolve ( [ err , server ] ) ;
311
+ err ? reject ( err ) : resolve ( server ) ;
308
312
} ) ;
309
313
connected . apply ( null , args ) ;
310
314
} ) ;
@@ -317,26 +321,30 @@ async function createHttp(httpConfig, log) {
317
321
async function createHttps ( ssl , log , h2 ) {
318
322
if ( typeof ssl === 'undefined' ) {
319
323
log ( 'https | no options.https; no server' ) ;
320
- return [ null , null ] ;
324
+ return null ;
321
325
}
322
326
323
327
if ( Array . isArray ( ssl ) ) {
324
328
return await createMultiple ( createHttps , ssl , log , h2 ) ;
325
329
}
326
330
327
- return await new Promise ( resolve => {
328
- var port = ssl . port ,
329
- timeout = ssl . timeout ,
330
- server ,
331
- args ;
331
+ let
332
+ port = ssl . port ,
333
+ timeout = ssl . timeout ,
334
+ server ,
335
+ args ;
332
336
333
- var finalHttpsOptions = assign ( { } , ssl , {
334
- //
335
- // Load default SSL key, cert and ca(s).
336
- //
337
- key : normalizePEMContent ( ssl . root , ssl . key ) ,
338
- cert : normalizeCertContent ( ssl . root , ssl . cert , ssl . key ) ,
339
- ca : normalizeCA ( ssl . root , ssl . ca ) ,
337
+ const [ key , cert , ca ] = await Promise . all ( [
338
+ normalizePEMContent ( ssl . root , ssl . key ) ,
339
+ normalizeCertContent ( ssl . root , ssl . cert , ssl . key ) ,
340
+ normalizeCA ( ssl . root , ssl . ca )
341
+ ] ) ;
342
+
343
+ return await new Promise ( async ( resolve , reject ) => {
344
+ const finalHttpsOptions = assign ( { } , ssl , {
345
+ key,
346
+ cert,
347
+ ca,
340
348
//
341
349
// Properly expose ciphers for an A+ SSL rating:
342
350
// https://certsimple.com/blog/a-plus-node-js-ssl
@@ -352,7 +360,7 @@ async function createHttps(ssl, log, h2) {
352
360
} ) ;
353
361
354
362
if ( ssl . sni && ! finalHttpsOptions . SNICallback ) {
355
- finalHttpsOptions . SNICallback = getSNIHandler ( ssl ) ;
363
+ finalHttpsOptions . SNICallback = await getSNIHandler ( ssl ) ;
356
364
}
357
365
358
366
log ( 'https | listening on %d' , port ) ;
@@ -369,21 +377,26 @@ async function createHttps(ssl, log, h2) {
369
377
}
370
378
371
379
args . push ( function listener ( err ) {
372
- resolve ( [ err , server ] ) ;
380
+ err ? reject ( err ) : resolve ( server ) ;
373
381
} ) ;
374
382
connected . apply ( null , args ) ;
375
383
} ) ;
376
384
}
377
385
378
386
async function createMultiple ( createFn , configArray , log ) {
379
- const errorsOrServers = await Promise . all (
387
+ const errorsOrServers = await Promise . allSettled (
380
388
configArray . map ( cfg => createFn ( cfg , log ) )
381
389
) ;
382
- const errors = [ ] ,
383
- servers = [ ] ;
384
- for ( const [ error , server ] of errorsOrServers ) {
385
- error && errors . push ( error ) ;
386
- server && servers . push ( server ) ;
390
+
391
+ const errors = [ ] , servers = [ ] ;
392
+ for ( const result of errorsOrServers ) {
393
+ result . reason && errors . push ( result . reason ) ;
394
+ result . value && servers . push ( result . value ) ;
395
+ }
396
+
397
+ if ( errors . length ) {
398
+ throw errors ;
399
+ } else {
400
+ return servers ;
387
401
}
388
- return [ errors . length ? errors : null , servers ] ;
389
402
}
0 commit comments