Begin a FAQ
[oweals/peertube.git] / scripts / check.js
1 #!/usr/bin/env node
2
3 'use strict'
4
5 const series = require('async/series')
6 const request = require('request')
7 const WebSocket = require('ws')
8
9 const constants = require('../server/initializers/constants')
10 const requestHeaders = {
11   'Range': '',
12   'Keep-Alive': '',
13   'User-Agent': 'Mozilla',
14   'Cache-Control': 'no-cache',
15   'Content-Type': '',
16   'Host': 'example.com',
17   'Access-Control-Request-Method': 'GET',
18   'Access-Control-Request-Headers': 'range'
19 }
20
21 series([
22   pingServer,
23   checkCORSTorrent,
24   checkCORSWebSeed,
25   checkTracker
26 ], function () {
27   process.exit(0)
28 })
29
30 // ---------------------------------------------------------------------------
31
32 function pingServer (callback) {
33   const pingUrl = constants.CONFIG.WEBSERVER.URL + '/api/v1/ping'
34   console.log('Checking server is up (%s)...', pingUrl)
35
36   request(pingUrl, function (err, res, body) {
37     if (!err && res.statusCode === 200 && body === 'pong') {
38       console.log('SUCCESS.')
39     } else {
40       console.log('FAIL.')
41     }
42
43     callback()
44   })
45 }
46
47 function checkCORSTorrent (callback) {
48   const torrentUrl = constants.CONFIG.WEBSERVER.URL + '/static/torrents/test.torrent'
49   console.log('Checking CORS headers for the torrent (%s)...', torrentUrl)
50
51   request({
52     method: 'OPTIONS',
53     uri: torrentUrl,
54     headers: requestHeaders
55   }, function (err, res) {
56     if (err || isThereValidCORSHeaders(res) === false) {
57       console.error('FAIL.')
58     } else {
59       console.log('SUCCESS.')
60     }
61
62     callback()
63   })
64 }
65
66 function checkCORSWebSeed (callback) {
67   const webseedUrl = constants.CONFIG.WEBSERVER.URL + '/static/webseed/test.mp4'
68   console.log('Checking CORS headers for the video (%s)...', webseedUrl)
69
70   request({
71     method: 'OPTIONS',
72     uri: webseedUrl,
73     headers: requestHeaders
74   }, function (err, res) {
75     if (err || isThereValidCORSHeaders(res) === false) {
76       console.error('FAIL.')
77     } else {
78       console.log('SUCCESS.')
79     }
80
81     callback()
82   })
83 }
84
85 function checkTracker (callback) {
86   const trackerUrl = constants.CONFIG.WEBSERVER.WS + '://' +
87                      constants.CONFIG.WEBSERVER.HOST +
88                      '/tracker/socket'
89   console.log('Checking tracker websocket (%s)...', trackerUrl)
90
91   let ws = null
92   ws = new WebSocket(trackerUrl)
93
94   const timeout = setTimeout(failed, 1000)
95   ws.on('open', onOpen)
96
97   function onOpen () {
98     clearTimeout(timeout)
99     ws.close()
100
101     console.log('SUCCESS.')
102     callback()
103   }
104
105   function failed () {
106     ws.removeListener('open', onOpen)
107     ws.close()
108
109     console.log('FAILED.')
110     callback()
111   }
112 }
113
114 function isThereValidCORSHeaders (res) {
115   let fail = false
116
117   // Check Access-Control-Allow-Origin
118   const headerAllowOriginKey = 'access-control-allow-origin'
119   const headerAllowOrigin = res.headers[headerAllowOriginKey]
120
121   if (!headerAllowOrigin) {
122     console.error(headerAllowOriginKey + ' is not present.')
123     fail = true
124   } else if (headerAllowOrigin !== '*') {
125     console.error(headerAllowOriginKey + ' does not equal "*".')
126     fail = true
127   }
128
129   // Check Access-Control-Allow-Methods
130   const headerAllowMethodsKey = 'access-control-allow-methods'
131   const headerAllowMethods = res.headers[headerAllowMethodsKey]
132   if (!headerAllowMethods) {
133     console.error(headerAllowMethodsKey + ' is not present.')
134     fail = true
135   } else {
136     const allowMethodsMissed = findPatternNotInString(headerAllowMethods, [ 'get' ])
137     if (allowMethodsMissed !== null) {
138       console.error(headerAllowMethodsKey + ' misses the ' + allowMethodsMissed + ' method.')
139       fail = true
140     }
141   }
142
143   // Check Access-Control-Allow-Headers
144   const headerAllowHeadersKey = 'access-control-allow-headers'
145   const headerAllowHeaders = res.headers[headerAllowHeadersKey]
146   if (!headerAllowHeaders) {
147     console.error(headerAllowHeadersKey + ' is not present.')
148     fail = true
149   } else {
150     const headersThatShouldBePresent = [
151       'Range'
152     ]
153     const allowHeadersMissed = findPatternNotInString(headerAllowHeaders, headersThatShouldBePresent)
154     if (allowHeadersMissed !== null) {
155       console.error(headerAllowHeadersKey + ' misses the ' + allowHeadersMissed + ' header.')
156       fail = true
157     }
158   }
159
160   return !fail
161 }
162
163 function findPatternNotInString (stringChain, patterns) {
164   let res = null
165   const stringChainLowerCase = stringChain.toLowerCase()
166
167   patterns.forEach(function (pattern) {
168     if (stringChainLowerCase.indexOf(pattern.toLowerCase()) === -1) {
169       res = pattern
170     }
171   })
172
173   return res
174 }