Switch to acorn-based JS templates with classes, ids, scripts, template strings
[jst_server.git] / server.js
1 let assert = require('assert')
2 let config = require('./config')
3 let site = require('./site')
4
5 let caching = false
6 let set_caching = value => {
7   caching = value
8 }
9
10 let serve = (res, status, mime_type, data) => {
11   res.statusCode = status
12   // html files will be direct recipient of links/bookmarks so can't have
13   // a long lifetime, other files like css or images are often large files
14   // and won't change frequently (but we'll need cache busting eventually)
15   if (caching && mime_type !== config.mime_types_html)
16     res.setHeader('Cache-Control', 'max-age=3600')
17   res.setHeader('Content-Type', mime_type)
18   res.setHeader('Content-Length', data.length)
19   res.end(data)
20 }
21
22 let die = res => {
23   let body = '<html><body>Page not found</body></html>'
24   serve(res, 404, config.mime_type_html, Buffer.from(body))
25 }
26
27 let redirect = (res, location) => {
28   res.statusCode = 301
29   res.setHeader('Location', location)
30   res.end('Redirecting to ' + location)
31 }
32
33 let app = async (req, res, protocol) => {
34   await config.refresh()
35   try {
36     let domain_name = req.headers.host || 'localhost'
37     let temp = domain_name.indexOf(':')
38     let port_suffix = temp === -1 ? '' : domain_name.substring(temp)
39     domain_name = domain_name.substring(
40       0,
41       domain_name.length - port_suffix.length
42     )
43     if (!Object.prototype.hasOwnProperty.call(config.sites, domain_name)) {
44       console.log('nonexistent site', domain_name)
45       die(res)
46       return
47     }
48     temp = config.sites[domain_name]
49     switch (temp.type) {
50     case 'redirect':
51       let new_domain = temp.domain
52       console.log('redirecting', domain_name, 'to', new_domain)
53       redirect(res, protocol + '://' + new_domain + port_suffix + req.url)
54       break
55     case 'site':
56       await site.app(domain_name, temp.root, req, res, protocol)
57       break
58     default:
59       assert(false)
60     }
61   }
62   catch (err) {
63     let message = (err.stack || err.message).toString()
64     console.error(message)
65     let body = '<html><body><pre>' + message + '</pre></body></html>'
66     serve(res, 500, config.mime_type_html, Buffer.from(body, 'utf8'))
67   }
68 }
69
70 exports.set_caching = set_caching
71 exports.serve = serve
72 exports.die = die
73 exports.redirect = redirect
74 exports.app = app