6a631af946d81c40b4935c7b06daaeb8b51b9d3a
2 * @file Node entry and main driver
3 * @author Jordan Lavatai, Ken Grimes
6 * @copyright jk software 2017
7 * @summary HTTP(S) Router that uses the first directory in the requested URL
10 const fs
= require('fs')
11 const ws
= require('ws')
12 const path
= require('path')
13 const http
= require('http')
14 const https
= require('https')
15 const getport
= require('get-port')
16 const mime
= require('mime')
17 const opts
= require('./opts.js')
19 const skelPage
= fs
.readFileSync('./skel.html', { encoding
: 'utf8' }).split('<!--STRAPP_SRC-->')
20 const clientJS
= fs
.readFileSync(opts
['client-js'])
21 const hostJS
= fs
.readFileSync(opts
['host-js'])
24 const httpsOpts
= (opts
['no-tls'] ?
27 key
: fs
.readFileSync(opts
['ca-key']),
28 cert
: fs
.readFileSync(opts
['ca-cert'])
31 const routeConnection
= (request
,response
) => {
32 const serveFile
= (fPath
) => {
33 fs
.readFile(fPath
, { encoding
: 'utf8' }, (err
, data
) => {
34 if (err
|| data
== undefined) {
39 response
.write(200, mime
.lookup(fPath
))
45 const htArgv
= request
.url
.slice(1).split("?")
47 let routePath
= htArgv
[0].split(path
.sep
)
48 let routeName
= routePath
[0]
50 routeName
= opts
['index']
51 if (routeName
in opts
['bindings']) {
52 const followBind
= (dir
, fPaths
) => {
53 fs
.readdir(dir
, (err
, file
) => {
56 else if (fPaths
.length
== 0)
57 serveFile(`${dir}/index.html`)
58 else if (fPaths
[0] !== '..' || path
.normalize(`${dir}${path.sep}..`).includes(path
.normalize(opts
['bindings'][routeName
]))) {
59 let nextFPath
= fPaths
.shift()
60 if (nextFPath
in fPaths
)
61 followBind(`${dir}${path.sep}${nextFPath}`, fPaths
)
63 response
.writeHead(404)
68 console
.log(`SEC: Ignored '..' in URL ${request.url}`)
73 followBind(opts
['bindings'][routeName
], htArgv
[0].split(path
.sep
).slice(1))
75 else if (routeName
in routes
) {
76 const route
= routes
[routeName
]
77 response
.writeHead(200, { 'Content-Type': 'text/html' })
78 response
.write(`${skelPage[0]}${clientJS}${skelPage[1]}`)
80 route
.socket
.send(request
.headers
['x-forwarded-for'] || request
.connection
.remoteAddress
)
83 routes
[htArgv
[0]] = true
85 newRoute
.host
= request
.headers
['x-forwarded-for'] || request
.connection
.remoteAddress
86 getport().then( (port
) => {
89 newRoute
.httpd
= http
.createServer()
91 newRoute
.httpd
= https
.createServer(httpsOpts
)
92 newRoute
.httpd
.listen(newRoute
.port
)
93 newRoute
.ws
= new ws
.Server( { server
: newRoute
.httpd
} )
94 newRoute
.ws
.on('connection', (ws
) => { console
.log("socket connected"); newRoute
.socket
= ws
; ws
.send("CONNECTED") } )
95 newRoute
.ws
.on('message', (msg
) => { console
.log("Received message" + msg
) })
96 console
.log("Listening for websocket " + newRoute
.host
+ " on port " + newRoute
.port
)
97 routes
[htArgv
[0]] = newRoute
99 response
.writeHead(200, { 'Content-Type': 'text/html' })
100 response
.write(skelPage
[0] + 'const _strapp_port = \'' + newRoute
.port
+ '\'\n' + hostJS
+ skelPage
[1])
106 const router
= ((opts
['no-tls']) ?
107 http
.createServer(routeConnection
) :
108 https
.createServer(httpsOpts
, routeConnection
))
109 .listen(opts
['port'])
111 //TODO: if ("electron" in process.versions) open a local renderwindow, and route to it