1 const fs
= require('fs')
2 const ws
= require('ws')
3 const https
= require('https')
4 const getport
= require('get-port')
5 const mime
= require('mime')
7 const argv
= require('minimist')(process
.argv
.slice(2), {
8 string
: [ 'ca-cert', 'ca-key', 'config', 'client-js', 'host-js', 'electron', 'port' ],
9 boolean: [ 'remote-host' ],
19 default: { config
: undefined,
20 'client-js': 'client.js',
22 'ca-cert': 'stunnel.cert',
23 'ca-key': 'stunnel.key',
29 console
.log(process
.argv
.join(" ") + '\nUnknown operator: ' + opt
+ `
30 Usage: strapp [OPTION]...
31 Route https connections from a hardware port to a remote host, and initiate
32 peer-to-peer connection with clients.
35 -c, --config=path Configuration file to use (/etc/strapp.conf)
36 - overridden by command line opts
37 -j, --client-js=path Path to the client Strapp code (./strapp-client.js)
38 -J, --host-js=path Path to the host Strapp code (./strapp-host.js)
39 -C, --ca-cert=path Accessible location of the CA Cert (./stunnel.cert)
40 -K, --ca-key=path Accessible location of the CA Key (./stunnel.key)
41 -p, --port=number The local port to bind HTTPS listener to (2443)
44 -e, --electron=route Route to the local electron user (nil)
45 - enables optional electron dependency
46 -d, --dedicated=route Route all incoming connections to this route (nil)
47 - used in conjunction with '-e=my_route'
55 //TODO: if (argv['config'] !== undefined), read and apply to argv without overwrite
56 if (argv
['www-path'] == undefined)
57 argv
['www-path'] = 'www'
58 else if (String(argv
['www-path']).endsWith('/'))
59 argv
['www-path'] = argv
['www-path'].slice(0,-1)
62 key
: fs
.readFileSync(argv
['ca-key']),
63 cert
: fs
.readFileSync(argv
['ca-cert'])
65 const skelPage
= String(fs
.readFileSync('skel.html')).split("<!--STRAPP-->")
66 const clientJS
= fs
.readFileSync(argv
['client-js'])
67 const hostJS
= fs
.readFileSync(argv
['host-js'])
71 fs
.readdirSync(argv
['www-path']).forEach((file
) => {
73 fileBuf
[file
] = { mime
: mime
.lookup(argv
['www-path'] + '/' + file
),
74 data
: fs
.readFileSync(argv
['www-path'] + '/' + file
)
79 const router
= https
.createServer(routerOpts
, (request
, response
) => {
80 const htArgv
= request
.url
.slice(1).split("?")
81 let routeName
= htArgv
[0].split('/')[0]
83 routeName
= 'index.html'
84 if (routeName
.indexOf('.') != -1) {
85 if (routeName
in fileBuf
) {
86 response
.writeHead(200, { 'Content-Type': fileBuf
[routeName
].mime
})
87 response
.write(fileBuf
[routeName
].data
)
90 if ('404.html' in fileBuf
) {
91 response
.writeHead(404, fileBuf
['404.html'].mime
)
92 response
.write(fileBuf
['404.html'].data
)
95 response
.writeHead(404)
99 else if (routeName
in routes
) {
100 const route
= routes
[routeName
]
101 response
.writeHead(200, { 'Content-Type': 'text/html' })
102 response
.write(skelPage
[0] + clientJS
+ skelPage
[1])
104 route
.socket
.send(request
.headers
['x-forwarded-for'] || request
.connection
.remoteAddress
)
107 routes
[htArgv
[0]] = true
109 newRoute
.host
= request
.headers
['x-forwarded-for'] || request
.connection
.remoteAddress
110 getport().then( (port
) => {
112 newRoute
.httpd
= https
.createServer(routerOpts
, (request
, response
) => {
113 }).listen(newRoute
.port
)
115 newRoute
.ws
= new ws
.Server( { server
: newRoute
.httpd
} )
116 newRoute
.ws
.on('connection', (ws
) => { console
.log("socket connected"); newRoute
.socket
= ws
; ws
.send("CONNECTED") } )
117 newRoute
.ws
.on('message', (msg
) => { console
.log("Received message" + msg
) })
118 console
.log("Listening for websocket " + newRoute
.host
+ " on port " + newRoute
.port
)
119 routes
[htArgv
[0]] = newRoute
121 response
.writeHead(200, { 'Content-Type': 'text/html' })
122 response
.write(skelPage
[0] + 'const _strapp_host = \'www.strapp.io\'\n\tconst _strapp_port = \'' + newRoute
.port
+ '\'\n' + hostJS
+ skelPage
[1])
126 }).listen(argv
['port'])
128 //TODO: if ("electron" in process.versions) open a local renderwindow, and route to it