UNPKG

3.92 kBJavaScriptView Raw
1/**
2 * Module Dependencies
3 *
4 * @ignore
5 */
6var bodyParser = require('body-parser')
7var contentLength = require('express-content-length-validator')
8var cors = require('cors')
9var Dispatcher = require('structure-dispatcher').default
10var express = require('express')
11var helmet = require('helmet')
12var hpp = require('hpp')
13var logger = require('structure-logger')
14var path = require('path')
15var Router = require('structure-router')
16var serveStatic = require('serve-static')
17var WebsocketServer = require('structure-websocket-server')
18
19function removePoweredBy(req, res, next) {
20 res.removeHeader('X-Powered-By')
21 next()
22}
23
24/**
25 * Server Class
26 *
27 * @public
28 * @class Server
29 */
30class Server {
31
32 /**
33 * Server constructor
34 *
35 * @public
36 * @constructor
37 * @param {Object} options - Options
38 */
39 constructor(options = {}) {
40
41 var defaults = {
42 cursors: options.cursors || [],
43 db: true,
44 drain: true,
45 sockets: true
46 }
47
48 this.options = Object.assign({}, defaults, options)
49
50 this.server = express()
51
52 /*
53 TODO: Add whitelist
54 */
55 this.server.use(cors())
56
57 /*if(process.env.NODE_ENV != 'test') {
58 this.server.use(require('express-status-monitor')())
59 }*/
60 this.server.use(serveStatic(path.join(__dirname, '../public')))
61 this.server.use(bodyParser.urlencoded({extended: true}))
62 this.server.use(bodyParser.json({strict: false}))
63 //this.server.use(removePoweredBy)
64 this.server.use(helmet())
65 this.server.use(hpp())
66 this.server.use(contentLength.validateMax({max: process.env.MAX_CONTENT_LENGTH, status: 400, message: 'stop it!'}))
67
68 if(process.env.NODE_ENV != 'test') {
69 this.server.use(this.logRequestInfo)
70 }
71
72 this.router = options.router || new Router({
73 dispatcher: options.dispatcher || new Dispatcher(),
74 routes: options.routes
75 })
76
77 this.router.start(this.server)
78
79 let routes = []
80
81 for(let i = 0, l = this.router.routesList.length; i < l; i++) {
82 const item = this.router.routesList[i]
83 let path = (item.routeName) ? `/${item.routeName}${item.route.path}` : item.route.path
84 path = path.replace(/\/$/, '')
85
86 const key = Object.keys(item.methods).map(function(k) {
87 return k.toUpperCase()
88 })[0]
89
90 const row = {}
91 row[key] = path
92
93 routes.push(row)
94 }
95
96 // For debuggin
97 this.routesList = routes
98
99 this.server.get(`/api/${process.env.API_VERSION}`, function routesListHandler(req, res) {
100
101 res.json({
102 routes
103 })
104
105 })
106
107 }
108
109 closeCursors() {
110 var cursors = require('./cursors')
111
112 for(let i = 0, l = cursors.length; i < l; i++) {
113 var cursor = cursors[i]
114 cursor.close()
115 }
116
117 cursors = []
118
119 }
120
121 /**
122 * Log each HTTP request's method and url
123 *
124 * @private
125 * @param {Object} req - Express req
126 * @param {Object} res - Express res
127 * @param {Function} next - Express next
128 */
129 logRequestInfo(req, res, next) {
130
131 logger.info(req.method, req.originalUrl)
132 next()
133
134 }
135
136 /**
137 * Start the HTTP Server
138 *
139 * @public
140 */
141 start() {
142
143 this.server = this.server.listen(this.options.port || process.env.EXPRESS_PORT)
144
145 if(this.options.sockets) {
146 this.wss = new WebsocketServer(this.server)
147 }
148
149 if(this.options.db) {
150 this.cursors = []
151 }
152
153 logger.debug('Structure API started at:', `http://localhost:${process.env.EXPRESS_PORT}`)
154
155 }
156
157 /**
158 * Stop the HTTP Server
159 *
160 * @public
161 */
162 stop() {
163
164 if(this.options.db) {
165 var r = require('../lib/database/driver')
166 if(this.options.drain) r.getPoolMaster().drain()
167 this.closeCursors()
168 }
169
170 if(this.options.sockets) {
171 this.wss.stop()
172 }
173
174 this.server.close()
175
176 }
177
178 /**
179 * Add Express middleware to the Express server object
180 *
181 * @public
182 */
183 use() {
184
185 this.server.use.apply(this.server, arguments)
186
187 }
188
189}
190
191module.exports = Server