Add requests parameters validations
[oweals/peertube.git] / server.js
1 ;(function () {
2   'use strict'
3
4   // ----------- Constantes -----------
5   global.API_VERSION = 'v1'
6
7   // ----------- Node modules -----------
8   var express = require('express')
9   var expressValidator = require('express-validator')
10   var path = require('path')
11   var morgan = require('morgan')
12   var bodyParser = require('body-parser')
13   var multer = require('multer')
14   var TrackerServer = require('bittorrent-tracker').Server
15   var WebSocketServer = require('ws').Server
16   var app = express()
17   var http = require('http')
18
19   // ----------- Checker -----------
20   var checker = require('./src/checker')
21
22   var miss = checker.checkConfig()
23   if (miss.length !== 0) {
24     // Do not use logger module
25     console.error('Miss some configurations keys.', { miss: miss })
26     process.exit(0)
27   }
28
29   checker.createDirectories()
30
31   // ----------- PeerTube modules -----------
32   var config = require('config')
33   var logger = require('./src/logger')
34   var routes = require('./routes')
35   var api = require('./routes/api/' + global.API_VERSION)
36   var utils = require('./src/utils')
37   var videos = require('./src/videos')
38   var webtorrent = require('./src/webTorrentNode')
39
40   var compression
41   var port = config.get('listen.port')
42   var uploads = config.get('storage.uploads')
43
44   // ----------- Command line -----------
45
46   // ----------- App -----------
47   app.use(morgan('combined', { stream: logger.stream }))
48   app.use(bodyParser.json())
49   app.use(multer({ dest: uploads }))
50   app.use(bodyParser.urlencoded({ extended: false }))
51   app.use(expressValidator())
52
53   // ----------- Views, routes and static files -----------
54
55   if (process.env.NODE_ENV === 'production') {
56     // logger.log('Production : static files in dist/\n')
57
58     // GZip compression
59     compression = require('compression')
60     app.use(compression())
61
62     // A month
63     var maxAge = 86400000 * 30
64
65     // TODO
66     app.get(/^\/(index|(partials\/[a-z\/]+))?$/, function (req, res, next) {
67       if (req.url === '/') {
68         req.url = '/index'
69       }
70
71       req.url += '.html'
72       next()
73     })
74
75     app.use(express.static(path.join(__dirname, '/dist/public'), { maxAge: maxAge }))
76     app.use(express.static(path.join(__dirname, '/dist/views'), { maxAge: maxAge }))
77   } else {
78     // Livereload
79     app.use(require('connect-livereload')({
80       port: 35729
81     }))
82
83     require('segfault-handler').registerHandler()
84
85     app.use(express.static(path.join(__dirname, '/public'), { maxAge: 0 }))
86
87     // Jade template from ./views directory
88     app.set('views', path.join(__dirname, '/views'))
89     app.set('view engine', 'jade')
90
91     // Views routes
92     app.use('/', routes)
93   }
94
95   // ----------- Routes -----------
96   var api_route = '/api/' + global.API_VERSION
97   app.use(api_route + '/videos', api.videos)
98   app.use(api_route + '/remotevideos', api.remoteVideos)
99   app.use(api_route + '/pods', api.pods)
100
101   // ----------- Tracker -----------
102
103   var trackerServer = new TrackerServer({
104     http: false,
105     udp: false,
106     ws: false,
107     dht: false
108   })
109
110   trackerServer.on('error', function (err) {
111     logger.error(err)
112   })
113
114   trackerServer.on('warning', function (err) {
115     logger.error(err)
116   })
117
118   var server = http.createServer(app)
119   var wss = new WebSocketServer({server: server, path: '/tracker/socket'})
120   wss.on('connection', function (ws) {
121     trackerServer.onWebSocketConnection(ws)
122   })
123
124   // ----------- Errors -----------
125
126   // Catch 404 and forward to error handler
127   app.use(function (req, res, next) {
128     var err = new Error('Not Found')
129     err.status = 404
130     next(err)
131   })
132
133   // Prod : no stacktraces leaked to user
134   if (process.env.NODE_ENV === 'production') {
135     app.use(function (err, req, res, next) {
136       logger.error('Error : ' + err.message, { error: err })
137       res.status(err.status || 500)
138       res.render('error', {
139         message: err.message,
140         error: {}
141       })
142     })
143   } else {
144     app.use(function (err, req, res, next) {
145       logger.error('Error : ' + err.message, { error: err })
146       res.status(err.status || 500)
147       res.render('error', {
148         message: err.message,
149         error: err
150       })
151     })
152   }
153
154   // ----------- Create the certificates if they don't already exist -----------
155   utils.createCertsIfNotExist(function (err) {
156     if (err) throw err
157     // Create/activate the webtorrent module
158     webtorrent.create(function () {
159       function cleanForExit () {
160         utils.cleanForExit(webtorrent.app)
161       }
162
163       function exitGracefullyOnSignal () {
164         process.exit()
165       }
166
167       process.on('exit', cleanForExit)
168       process.on('SIGINT', exitGracefullyOnSignal)
169       process.on('SIGTERM', exitGracefullyOnSignal)
170
171       // ----------- Make the server listening -----------
172       server.listen(port, function () {
173         videos.seedAll(function () {
174           logger.info('Seeded all the videos')
175           logger.info('Server listening on port %d', port)
176           app.emit('ready')
177         })
178       })
179     })
180   })
181
182   module.exports = app
183 })()