UNPKG

4.45 kBJavaScriptView Raw
1/*!
2* Srcerer, server
3* Copyright(c) 2010-2017 Jesse Tijnagel (Guilala)
4* MIT Licensed
5*/
6
7/*jslint node: true */
8"use strict";
9
10// nodejs
11process.on("uncaughtException", (err) => {
12 console.error("\x1b[31m%s: \x1b[33m%s", err, err.stack);
13});
14
15// require
16const os = require("os");
17const path = require("path");
18const url = require("url");
19const express = require("express");
20const ws = require("ws").Server;
21const compression = require("compression");
22const bodyParser = require("body-parser");
23const healthcheck = require("express-healthcheck");
24
25// local
26const util = require("./util");
27const mountPoints = require("./mountPoints");
28
29// env
30const host = os.hostname();
31const root = path.dirname(require.main.filename) + "/";
32
33// conditions
34const checkConditions = function(done) {
35 var unmet = [];
36 var conditions = {
37 serverConfiguration: this.conf,
38 domain: this.conf.domain,
39 port: this.conf.port,
40 root: this.conf.root,
41 name: this.conf.name,
42 version: this.conf.version
43 };
44
45 for(var key in conditions) {
46 if(conditions.hasOwnProperty(key) && !conditions[key]) {
47 unmet.push(key);
48 }
49 }
50
51 if(unmet.length) {
52 console.error(`Unmet conditions: ${unmet}`);
53 } else {
54 done();
55 }
56};
57
58// configure express
59const configureExpress = function(done) {
60 this.server = require("http").createServer();
61 this.express = express();
62 this.router = express.Router();
63 this.static = express.static;
64
65 this.express.disable('x-powered-by');
66 this.express.set("env", "production");
67 this.express.set("title", this.conf.name);
68 this.express.set("version", this.conf.version);
69 this.express.set("trust proxy", this.conf.domain); // X-Forwarded-* headers
70 this.express.use(compression());
71 this.express.use(bodyParser.json());
72 this.express.use("/healthcheck", healthcheck());
73
74 this.express.use(bodyParser.urlencoded({
75 extended: true
76 }));
77
78 this.router.use((req, res, next) => {
79 res.respond = {}; // json response
80 req.runtime = this; // this runtime
81 next();
82 });
83
84 done();
85};
86
87// route socket requests
88const routeSockets = function(done) {
89 // web socket server
90 this.wss = new ws({
91 server: this.server
92 });
93
94 // web socket connections
95 this.wss.on("connection", (ws) => {
96 if(ws.protocol) {
97 const context = this.mount.socket[ws.protocol];
98
99 if(context && context.root) {
100 require(
101 path.resolve(
102 context.root,
103 context.configuration.script
104 )
105 ).call({
106 context: context,
107 mountPoint: ws.protocol,
108 runtime: this,
109 ws: ws
110 });
111 } else {
112 console.error("server, routeSockets: unknown protocol:", ws.protocol);
113 ws.terminate();
114 }
115 } else {
116 console.error("server, routeSockets: protocol undefined.");
117 ws.terminate();
118 }
119 });
120
121 done();
122};
123
124// reply
125const reply = function(done) {
126 // reply errors
127 this.router.use(function(err, req, res, next){
128 if(err){
129 var status = 500;
130
131 console.error(err);
132 if (req.xhr) {
133 res.send({
134 error: status
135 });
136 } else {
137 res.sendStatus(status);
138 }
139 } else {
140 next();
141 }
142 });
143
144 done();
145};
146
147// export init
148module.exports = function(configuration) {
149 util.que({
150 conf: configuration,
151 mount: {
152 app: {},
153 extention: {},
154 io: {},
155 socket: {}
156 },
157 apps: {}
158 })
159
160 .add(checkConditions)
161 .add(configureExpress)
162 .add(mountPoints)
163 .add(routeSockets)
164 .add(reply)
165
166 .then(function(){
167 // apply routes
168 this.express.use("/", this.router);
169
170 // start express
171 this.server.on("request", this.express);
172 this.server.listen(this.conf.port, this.conf.domain, () => {
173 var serverInstance = this.server.address();
174
175 console.log("\n\x1b[0m%s\nSrcerer v%s \x1b[37m@ Node %s\x1b[36m @ %s",
176 new Date(),
177 this.conf.version,
178 process.version,
179 host
180 );
181
182 console.log("\x1b[0m%s\x1b[36m @ %s:%s on %s\x1b[0m\n",
183 this.conf.name,
184 serverInstance.address,
185 serverInstance.port,
186 serverInstance.family
187 );
188 });
189 });
190};
191