#!/usr/bin/env node
-var assert = require('assert')
-var BuildCache = require('build_cache')
-var commander = require('commander')
-var fs = require('fs')
-var http = require('http')
-var https = require('https')
-var jstemplate = require('jstemplate')
-var less = require('less/lib/less-node')
-var querystring = require('querystring')
-var util = require('util')
-var url = require('url')
-var zetjs = require('zetjs')
+let assert = require('assert')
+let BuildCache = require('build_cache')
+let commander = require('commander')
+let fs = require('fs')
+let http = require('http')
+let https = require('https')
+let jstemplate = require('jstemplate')
+let less = require('less/lib/less-node')
+let querystring = require('querystring')
+let util = require('util')
+let url = require('url')
+let zetjs = require('zetjs')
-var readFileAsync = util.promisify(fs.readFile)
-var statAsync = util.promisify(fs.stat)
+let readFileAsync = util.promisify(fs.readFile)
+let statAsync = util.promisify(fs.stat)
commander.version('1.0.0').option(
'-c, --enable-caching',
8443
).parse(process.argv)
-var sites = JSON.parse(fs.readFileSync('config/sites.json'))
-var mime_types = JSON.parse(fs.readFileSync('config/mime_types.json'))
-var mime_type_default = 'application/octet-stream'
-var mime_type_css = mime_types['css'] || mime_type_default
-var mime_type_html = mime_types['html'] || mime_type_default
-var build_cache_js = new BuildCache()
-var build_cache_json = new BuildCache()
-var build_cache_less = new BuildCache()
-var build_cache_text = new BuildCache()
-var build_cache_zet = new BuildCache()
+let sites = JSON.parse(fs.readFileSync('config/sites.json'))
+let mime_types = JSON.parse(fs.readFileSync('config/mime_types.json'))
+let mime_type_default = 'application/octet-stream'
+let mime_type_css = mime_types['css'] || mime_type_default
+let mime_type_html = mime_types['html'] || mime_type_default
+let build_cache_js = new BuildCache()
+let build_cache_json = new BuildCache()
+let build_cache_less = new BuildCache()
+let build_cache_text = new BuildCache()
+let build_cache_zet = new BuildCache()
-var serve = function(res, status, mime_type, data) {
+let serve = function(res, status, mime_type, data) {
res.statusCode = status
// html files will be direct recipient of links/bookmarks so can't have
// a long lifetime, other files like css or images are often large files
res.end(data)
}
-var die = function(res) {
- var body = '<html><body>Page not found</body></html>'
+let die = function(res) {
+ let body = '<html><body>Page not found</body></html>'
serve(res, 404, 'text/html; charset=utf-8', new Buffer(body, 'utf8'))
}
-var redirect = function(res, location) {
+let redirect = function(res, location) {
res.statusCode = 301
res.setHeader('Location', location)
res.end('Redirecting to ' + location)
}
-var app = async function(req, res, protocol) {
- var site = req.headers.host || 'localhost'
- var temp = site.indexOf(':')
- var port_suffix = temp === -1 ? '' : site.substring(temp)
+let app = async function(req, res, protocol) {
+ let site = req.headers.host || 'localhost'
+ let temp = site.indexOf(':')
+ let port_suffix = temp === -1 ? '' : site.substring(temp)
site = site.substring(0, site.length - port_suffix.length)
if (!sites.hasOwnProperty(site)) {
console.log('nonexistent site', site)
return
}
temp = sites[site]
+ let site_root
if (temp.type === 'redirect') {
- var site_domain = temp.domain
+ let site_domain = temp.domain
console.log('redirecting', site, 'to', site_domain)
redirect(res, protocol + '://' + site_domain + port_suffix + req.url)
return
}
else if (temp.type === 'site')
- var site_root = temp.root
+ site_root = temp.root
else
assert(false)
// parse the pathname portion of url
// this is actually cheating since it's not a complete url
- var parsed_url = url.parse(req.url, true)
- var path = parsed_url.pathname.split('/')
+ let parsed_url = url.parse(req.url, true)
+ let path = parsed_url.pathname.split('/')
// path must begin with /
if (path.length === 0 || path[0].length)
return die(res)
// path elements must be findable in the file system (thus can't be empty)
- var dir_name = ''
- var dir_name_is_pub = false
+ let dir_name = ''
+ let dir_name_is_pub = false
for (var i = 1; i < path.length - 1; ++i) {
dir_name += '/' + path[i]
if (path[i].length === 0 || path[i].charAt(0) === '.') {
console.log(site, 'bad path component', dir_name)
return die(res)
}
+ let stats
try {
- var stats = await statAsync(site_root + dir_name)
+ stats = await statAsync(site_root + dir_name)
}
catch (err) {
if (err.code !== 'ENOENT')
}
temp = file_name.lastIndexOf('.')
- var file_type = temp === -1 ? '' : file_name.substring(temp + 1)
- var mime_type = mime_types[file_type] || mime_type_default
+ let file_type = temp === -1 ? '' : file_name.substring(temp + 1)
+ let mime_type = mime_types[file_type] || mime_type_default
- var page = dir_name + '/' + file_name, data
+ let page = dir_name + '/' + file_name, data
if (dir_name_is_pub) {
try {
data = await readFileAsync(site_root + page)
case 'html':
temp = page + '.js'
try {
- var buffers = []
- var env = {
+ let buffers = []
+ let env = {
lang: 'en',
page: page,
query: parsed_url.query,
site: site,
site_root: site_root
}
- var out = str => {buffers.push(Buffer.from(str))}
- var req = async (str, type) => {
- var key = (
+ let out = str => {buffers.push(Buffer.from(str))}
+ let req = async (str, type) => {
+ let key = (
str.length > 0 && str.charAt(0) === '/' ?
site_root :
site_root + dir_name + '/'
switch (type) {
case undefined:
case 'js':
- var render_func = await build_cache_js.get(key)
+ let render_func = await build_cache_js.get(key)
if (render_func === undefined) {
console.log(site, 'compiling', key)
render_func = await jstemplate(key)
case 'css':
temp = page + '.less'
try {
- var key = site_root + temp
- var data = await build_cache_less.get(key)
+ let key = site_root + temp
+ let data = await build_cache_less.get(key)
if (data === undefined) {
console.log(site, 'compiling', key)
- var result = await less.render(
+ let result = await less.render(
await readFileAsync(site_root + temp, {encoding: 'utf-8'}),
{
//color: true,
console.log(site, 'file not found', page)
return die(res)
-
- // enable this when we want to serve particular files programmatically:
- //switch (path) {
- //case '/search.html':
- // var first = parseInt(parsed_url.query.first || '0')
- // var temp = sites[site].zet_index.search(
- // parsed_url.query.query,
- // first,
- // 10
- // )
- // console.log(
- // site,
- // 'search query',
- // parsed_url.query.query,
- // 'first', first,
- // 'results', temp.results.length,
- // 'total results',
- // temp.total_results
- // )
- // console.log('sites[site]', sites[site])
- // console.log('sites[site].globals', sites[site].globals)
- // //console.log('globals.menu', sites[site].globals.menu, 'globals.blog', sites[site].globals.blog)
- // var body = sites[site].render_search(
- // {
- // 'globals': sites[site].globals,
- // 'modules': sites[site].modules,
- // 'path': path,
- // 'search': {
- // 'query': parsed_url.query.query,
- // 'first': first,
- // 'results': temp.results,
- // 'total_results': temp.total_results
- // }
- // }
- // )
- // serve(res, 200, 'text/html; charset=utf-8', new Buffer(body, 'utf8'))
- // return
- //}
}
-var tryApp = function(req, res, protocol) {
+let tryApp = function(req, res, protocol) {
app(req, res, protocol).catch(
err => {
console.log(err.stack || err.message)
- var body =
+ let body =
'<html><body><pre>' +
(err.stack || err.message) +
'</pre></body></html>'
// proceeds in an unsupervised fashion to eventual completion or error
}
-if (commander.httpPort !== -1)
+if (commander.httpPort !== -1) {
http.createServer(
function(req, res) {
return tryApp(req, res, 'http')
}
).listen(commander.httpPort)
console.log('HTTP server listening on port', commander.httpPort)
-if (commander.httpsPort !== -1)
+}
+if (commander.httpsPort !== -1) {
https.createServer(
{
'cert': fs.readFileSync(commander.sslCert),
}
).listen(commander.httpsPort)
console.log('HTTPS server listening on port', commander.httpsPort)
+}