UNPKG

2.5 kBJavaScriptView Raw
1'use strict'
2
3const { check } = require('./configuration')
4const dispatcher = require('./dispatcher')
5const EventEmitter = require('events')
6const http = require('http')
7const https = require('https')
8const http2 = require('http2')
9const {
10 $configurationEventEmitter,
11 $configurationInterface
12} = require('./symbols')
13const defer = require('./defer')
14
15function createServer (configuration, requestHandler) {
16 const { httpOptions } = configuration
17 if (configuration.ssl) {
18 if (configuration.http2) {
19 return http2.createSecureServer({
20 key: configuration.ssl.key,
21 cert: configuration.ssl.cert,
22 ...httpOptions
23 }, requestHandler)
24 }
25 return https.createServer({
26 key: configuration.ssl.key,
27 cert: configuration.ssl.cert,
28 ...httpOptions
29 }, requestHandler)
30 }
31 if (configuration.http2) {
32 return http2.createServer(httpOptions, requestHandler)
33 }
34 return http.createServer(httpOptions, requestHandler)
35}
36
37function createServerAsync (eventEmitter, configuration, dispatcher) {
38 return new Promise((resolve, reject) => {
39 const server = createServer(configuration, dispatcher.bind(eventEmitter, configuration))
40 eventEmitter.emit('server-created', { configuration: configuration[$configurationInterface], server })
41 let { port } = configuration
42 if (port === 'auto') {
43 port = 0
44 }
45 server.listen(port, configuration.hostname, err => err ? reject(err) : resolve(server))
46 })
47}
48
49module.exports = jsonConfiguration => {
50 const eventEmitter = new EventEmitter()
51 const [serverAvailable, ready, failed] = defer()
52 check(jsonConfiguration)
53 .then(configuration => {
54 configuration[$configurationEventEmitter] = eventEmitter
55 configuration.listeners.forEach(register => register(eventEmitter))
56 return createServerAsync(eventEmitter, configuration, dispatcher)
57 .then(server => {
58 ready(server)
59 const { port } = server.address()
60 const { http2 } = configuration
61 eventEmitter.emit('ready', {
62 url: `${configuration.protocol}://${configuration.hostname || '0.0.0.0'}:${port}/`,
63 port,
64 http2
65 })
66 })
67 })
68 .catch(reason => {
69 failed(reason)
70 eventEmitter.emit('error', { reason })
71 })
72 eventEmitter.close = function () {
73 return serverAvailable
74 .then(server => {
75 return new Promise(resolve => server.close(() => resolve()))
76 })
77 }
78 return eventEmitter
79}