UNPKG

3.32 kBJavaScriptView Raw
1
2var util = require("../lib/util")
3, log = require("../lib/log")("app")
4
5
6module.exports = listen
7
8
9function listen(port) {
10 var exiting
11 , app = this
12 , options = app.options
13
14 process.on("uncaughtException", function(e) {
15 ;(options.errorLog || log.error)(
16 "\nUNCAUGHT EXCEPTION!\n" +
17 (e.stack || (e.name || "Error") + ": " + (e.message || e))
18 )
19 ;(options.exit || exit).call(app, 1)
20 })
21
22 process.on("SIGINT", function() {
23 if (exiting) {
24 log.info("Killing from SIGINT (got Ctrl-C twice)")
25 return process.exit()
26 }
27 exiting = true
28 log.info("Gracefully shutting down from SIGINT (Ctrl-C)")
29 ;(options.exit || exit).call(app, 0)
30 })
31
32 process.on("SIGTERM", function() {
33 log.info("Gracefully shutting down from SIGTERM (kill)")
34 ;(options.exit || exit).call(app, 0)
35 })
36
37 process.on("SIGHUP", function() {
38 log.info("Reloading configuration from SIGHUP")
39 app.listen(port, true)
40 })
41
42 app.listen = options.listen || _listen
43
44 app.listen(port)
45
46 return app
47}
48
49function _listen(port) {
50 var app = this
51 , options = app.options
52 , httpPort = process.env.PORT || port || 8080
53 , httpsPort = process.env.HTTPS_PORT || 8443
54 , secure = options.https || options.http2
55 , msg = "Listening"
56 , listenCount = 0
57
58 if (app.httpServer) app.httpServer.close()
59 if (app.httpsServer) app.httpsServer.close()
60 app.httpServer = app.httpsServer = null
61
62 app.httpServer = require("http")
63 .createServer(secure && options.forceHttps ? forceHttps : this)
64 .listen(httpPort, addMsg("http"))
65 .on("connection", setNoDelay)
66 .on("close", logClose("http"))
67
68 if (secure) {
69 app.httpsServer = (
70 options.http2 ?
71 require("http2").createSecureServer(secure, this) :
72 require("https").createServer(secure, this)
73 )
74 .listen(httpsPort, options.http2 ? addMsg("http2") : addMsg("https"))
75 .on("connection", setNoDelay)
76 .on("close", logClose(options.http2 ? "http2" : "https"))
77
78 if (secure.sessionReuse) {
79 var sessionStore = {}
80 , timeout = secure.sessionTimeout || 300
81
82 app.httpsServer
83 .on("newSession", function(id, data, cb) {
84 sessionStore[id] = data
85 cb()
86 })
87 .on("resumeSession", function(id, cb) {
88 cb(null, sessionStore[id] || null)
89 })
90 }
91 }
92
93 function addMsg(proto) {
94 listenCount++
95 return function() {
96 var addr = this.address()
97 msg += " " + proto + " at " + addr.address + ":" + addr.port
98 if (!--listenCount) {
99 log.info(msg)
100 }
101 }
102 }
103 function logClose(proto) {
104 return function() {
105 log.info("Stop listening " + proto)
106 }
107 }
108}
109
110function exit(code) {
111 var app = this
112 , softKill = util.wait(function() {
113 log.info("Everything closed cleanly")
114 process.exit(code)
115 }, 1)
116
117 app.emit("beforeExit", softKill)
118
119 try {
120 if (app.httpServer) app.httpServer.close().unref()
121 if (app.httpsServer) app.httpsServer.close().unref()
122 } catch(e) {}
123
124 setTimeout(function() {
125 log.warn("Kill (timeout)")
126 process.exit(code)
127 }, 5000).unref()
128
129 softKill()
130}
131
132function setNoDelay(socket) {
133 socket.setNoDelay(true)
134}
135
136function forceHttps(req, res) {
137 var port = process.env.HTTPS_PORT || 8443
138 , host = (req.headers.host || "localhost").split(":")[0]
139 , url = "https://" + (port == 443 ? host : host + ":" + port) + req.url
140
141 res.writeHead(301, {"Content-Type": "text/html", "Location": url})
142 res.end('Redirecting to <a href="' + url + '">' + url + '</a>')
143}
144
145