let fs_readFile = util.promisify(fs.readFile)
let fs_stat = util.promisify(fs.stat)
-let app = async (site, site_root, req, res, protocol) => {
+let Site = function(root) {
+ if (!this instanceof Site)
+ throw Error('Site is a constructor')
+ this.root = root
+}
+
+Site.prototype.app = async function(host, req, res, protocol) {
// parse the pathname portion of url
// this is actually cheating since it's not a complete url
let parsed_url = url.parse(req.url, true)
for (let 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)
+ console.log(host, 'bad path component', dir_name)
server.die(res)
return
}
let stats
try {
- stats = await fs_stat(site_root + dir_name)
+ stats = await fs_stat(this.root + dir_name)
}
catch (err) {
if (err.code !== 'ENOENT')
if (!dir_name_is_pub) {
let temp = dir_name + '.pub'
try {
- stats = await fs_stat(site_root + temp)
+ stats = await fs_stat(this.root + temp)
dir_name = temp
dir_name_is_pub = true
}
catch (err2) {
if (err2.code !== 'ENOENT')
throw err2
- console.log(site, 'directory not found', dir_name)
+ console.log(host, 'directory not found', dir_name)
server.die(res)
return
}
}
if (!stats.isDirectory()) {
- console.log(site, 'not directory', dir_name)
+ console.log(host, 'not directory', dir_name)
server.die(res)
return
}
if (file_name === '') {
path[path.length - 1] = 'index.html'
path = path.join('/')
- console.log(site, 'server.redirecting', parsed_url.pathname, 'to', path)
+ console.log(host, 'server.redirecting', parsed_url.pathname, 'to', path)
server.redirect(res, path + (parsed_url.search || ''))
return
}
config.mime_type_default
if (dir_name_is_pub) {
- temp = site_root + dir_name + '/' + file_name
+ temp = this.root + dir_name + '/' + file_name
try {
let data = await fs_readFile(temp)
console.log(
- site,
+ host,
'serving',
temp,
'length',
// (has no .pub component), though constructed in a roundabout way
temp = page + '.pub'
try {
- let data = await fs_readFile(site_root + temp)
+ let data = await fs_readFile(this.root + temp)
console.log(
- site,
+ host,
'serving',
temp,
'length',
switch (file_type) {
case 'html':
temp = page + '.jst'
+ let template
try {
+ template = await js_template(this.root, this.root, temp)
+ }
+ catch (err) {
+ if (err.code !== 'ENOENT') // note: err.code might be undefined
+ throw err
+ template = undefined
+ }
+ if (template !== undefined) {
let _out = []
- await (await js_template(site_root, site_root, temp))(
+ await template(
{
cookies: cookie.parse(req.headers.cookie || ''),
lang: 'en',
+ host: host,
method: req.method,
page: page,
query: parsed_url.query,
read_stream: req,
- resources: resources,
set_cookie: (key, value, expires, path) => {
res.setHeader(
'Set-Cookie',
';'
)
},
- site: site,
- site_root: site_root
+ site: this
},
_out
)
let data = Buffer.from(_out.join(''))
console.log(
- site,
+ host,
'serving',
temp,
'length',
server.serve(res, 200, mime_type, data)
return
}
- catch (err) {
- if (err.code !== 'ENOENT') // should check error type
- throw err
- }
break
case 'css':
temp = page + '.less'
try {
let data = await resources.get_less(
- site_root + temp,
- site_root,
+ this.root + temp,
+ this.root,
dir_name
)
console.log(
- site,
+ host,
'serving',
temp,
'length',
}
}
- let favicons = await resources.get_zip(site_root + '/favicons.zip')
+ let favicons = await resources.get_zip(this.root + '/favicons.zip')
if (Object.prototype.hasOwnProperty.call(favicons, page)) {
let data = favicons[page]
console.log(
- site,
+ host,
'serving',
page,
'length',
return
}
- console.log(site, 'file not found', page)
+ console.log(host, 'file not found', page)
server.die(res)
}
-exports.app = app
+module.exports = Site
"main": "jst_server.js",
"directories": {},
"dependencies": {
+ "BuildCache": "../build_cache.git/BuildCache-1.0.0.tgz",
+ "JSONCache": "../json_cache.git/JSONCache-1.0.0.tgz",
"babel-cli": "^6.26.0",
- "build_cache": "file:../build_cache.git/build_cache-1.0.0.tgz",
"commander": "^2.18.0",
"cookie": "^0.3.1",
"emailjs": "^2.2.0",
"fs": "^0.0.1-security",
"http": "^0.0.0",
"https": "^1.0.0",
- "js_template": "file:../js_template.git/acorn/js_template-6.0.2.tgz",
- "json_cache": "file:../json_cache.git/json_cache-1.0.0.tgz",
+ "js_template": "../js_template.git/acorn/js_template-v6.0.2.tgz",
"less": "^3.8.1",
"querystring": "^0.2.0",
"stream-buffers": "^3.0.2",
"url": "^0.11.0",
"xdate": "^0.8.2",
"yauzl": "^2.10.0",
- "zetjs": "file:../zettair.git/src/zetjs/zetjs-1.0.0.tgz"
+ "zetjs": "../zettair.git/src/zetjs/zetjs-1.0.0.tgz"
},
"devDependencies": {},
"scripts": {},
-let BuildCache = require('build_cache')
+let BuildCache = require('BuildCache')
+let JSONCache = require('JSONCache')
let emailjs = require('emailjs')
let fs = require('fs')
-let JSONCache = require('json_cache')
let less = require('less/lib/less-node')
var stream_buffers = require('stream-buffers')
let util = require('util')
)
let build_cache_less = new BuildCache()
-let get_less = (path, site_root, dir_name) => build_cache_less.get(
+let get_less = (path, root, dir_name) => build_cache_less.get(
path,
async result => {
console.log('compiling', path)
//lint: false,
//math: 0,
//modifyVars: null,
- paths: [site_root + dir_name],
+ paths: [root + dir_name],
//plugins: [],
//reUsePluginManager: true,
//rewriteUrls: false,
- rootpath: site_root//,
+ rootpath: root//,
//strictImports: false,
//strictUnits: false,
//urlArgs: ''
}
)
+let build_cache_zet = new BuildCache()
+let get_zet = path => build_cache_zet.get(
+ path,
+ async result => {
+ console.log('opening', path)
+ result.deps = [
+ path + '.map.0',
+ path + '.param.0',
+ path + '.v.0',
+ path + '.vocab.0'
+ ]
+ result.value = new zetjs.Index(path)
+ }
+)
+
let build_cache_zip = new BuildCache()
let get_zip = path => build_cache_zip.get(
path,
}
)
-let build_cache_zet = new BuildCache()
-let get_zet = path => build_cache_zet.get(
- path,
- async result => {
- console.log('opening', path)
- result.deps = [
- path + '.map.0',
- path + '.param.0',
- path + '.v.0',
- path + '.vocab.0'
- ]
- result.value = new zetjs.Index(path)
- }
-)
-
// this is for read/write JSON files
// they will not be reloaded from disk if modified
let try_mkdir = async path => {
throw err
}
}
-let json_cache = new JSONCache()
-json_cache.diag = true
+let json_cache = new JSONCache(true)
exports.get_email = get_email
exports.get_json = get_json
exports.get_less = get_less
exports.get_text = get_text
-exports.get_zip = get_zip
exports.get_zet = get_zet
+exports.get_zip = get_zip
exports.try_mkdir = try_mkdir
exports.json_cache = json_cache
+let Site = require('./Site')
let assert = require('assert')
let config = require('./config')
-let site = require('./site')
+let js_template = require('js_template')
let caching = false
let set_caching = value => {
res.end('Redirecting to ' + location)
}
+let site_cache = {}
+let site_factory_default = async root => new Site(root)
+
let app = async (req, res, protocol) => {
await config.refresh()
try {
- let domain_name = req.headers.host || 'localhost'
- let temp = domain_name.indexOf(':')
- let port_suffix = temp === -1 ? '' : domain_name.substring(temp)
- domain_name = domain_name.substring(
+ let host = req.headers.host || 'localhost'
+ let temp = host.indexOf(':')
+ let port_suffix = temp === -1 ? '' : host.substring(temp)
+ host = host.substring(
0,
- domain_name.length - port_suffix.length
+ host.length - port_suffix.length
)
- if (!Object.prototype.hasOwnProperty.call(config.sites, domain_name)) {
- console.log('nonexistent site', domain_name)
+ if (!Object.prototype.hasOwnProperty.call(config.sites, host)) {
+ console.log('nonexistent site', host)
die(res)
return
}
- temp = config.sites[domain_name]
+ temp = config.sites[host]
switch (temp.type) {
case 'redirect':
let new_domain = temp.domain
- console.log('redirecting', domain_name, 'to', new_domain)
+ console.log('redirecting', host, 'to', new_domain)
redirect(res, protocol + '://' + new_domain + port_suffix + req.url)
break
case 'site':
- await site.app(domain_name, temp.root, req, res, protocol)
+ let site_factory
+ try {
+ site_factory = await js_template(
+ temp.root,
+ temp.root,
+ 'site_factory.jst'
+ )
+ }
+ catch (err) {
+ if (err.code !== 'ENOENT') // note: err.code might be undefined
+ throw err
+ site_factory = site_factory_default
+ }
+ let site
+ if (
+ !Object.prototype.hasOwnProperty.call(site_cache, temp.root) ||
+ (site = site_cache[temp.root]).factory !== site_factory
+ ) {
+ site = {
+ factory: site_factory,
+ object: await site_factory(temp.root)
+ }
+ site_cache[temp.root] = site
+ }
+ await site.object.app(host, req, res, protocol)
break
default:
assert(false)