this.enable_caching = false
this.listen = []
this.mime_types = {}
- this.sites = {}
+ this.hosts = {}
+ this.roots = {}
this.mime_type_html = 'text/html; charset=utf-8'
this.mime_type_default = 'application/octet-stream'
this.resources = new Resources()
- this.resources_jst_cache = this.resources.ref(
- 'jst_cache',
- () => new Resources()
- )
- this.jst_cache = this.resources_jst_cache.ref(
- '.',
+ this.jst_cache = this.resources.ref(
+ 'jst_cache:.',
() => new JSTCache('.', {_jst_server: jst_server}, true)
)
}
this.mime_types['.html'] :
this.mime_type_default
- this.sites = config.sites
+ this.hosts = config.hosts
}
}
//console.log('parsed_url', parsed_url)
if (
- !Object.prototype.hasOwnProperty.call(this.sites, parsed_url.hostname)
+ !Object.prototype.hasOwnProperty.call(this.hosts, parsed_url.hostname)
) {
this.die(
response,
mime_type = this.mime_types[extension]
}
- let site = this.sites[parsed_url.hostname]
- await site.respond(
- {
- mime_type: mime_type,
- parsed_url: parsed_url,
- pathname: parsed_url.pathname,
- response: response,
- request: request,
- server: this
+ let host = this.hosts[parsed_url.hostname]
+ switch (host.type) {
+ case 'redirect':
+ let new_host = host.host
+ if (parsed_url.port !== undefined)
+ new_host += ':' + parsed_url.port
+ this.redirect(
+ response,
+ `${parsed_url.protocol}//${redirect}${request.url}`,
+ `redirecting ${parsed_url.host} to ${new_host}`
+ )
+ return
+ case 'site':
+ let root
+ if (Object.prototype.hasOwnProperty.call(this.roots, host.root))
+ root = this.roots[host.root]
+ else {
+ root = {
+ jst_cache: this.resources.ref(
+ `jst_cache:${host.root}`,
+ () => new JSTCache(host.root, {_jst_server: jst_server}, true)
+ ),
+ site: undefined
+ }
+ this.roots[host.root] = root
}
- )
- }
+ let config = await root.jst_cache.get(
+ `${host.root}/_config/site.jst`,
+ true
+ )
+ if (config !== undefined)
+ root.site = await config(this, host.root, root.site)
+ return root.site.respond(
+ {
+ mime_type: mime_type,
+ parsed_url: parsed_url,
+ pathname: parsed_url.pathname,
+ response: response,
+ request: request,
+ server: this
+ }
+ )
+ default:
+ assert(false)
+ }
+ }
catch (err) {
let message = (err.stack || err.message).toString()
this.serve(
-let Site = function(server) {
+let JSONCache = require('@ndcode/json_cache')
+let JSONCacheRW = require('@ndcode/json_cache_rw')
+let JSTCache = require('@ndcode/jst_cache')
+let LessCSSCache = require('@ndcode/less_css_cache')
+let MinCSSCache = require('@ndcode/min_css_cache')
+let MinJSCache = require('@ndcode/min_js_cache')
+let MinHTMLCache = require('@ndcode/min_html_cache')
+let MinSVGCache = require('@ndcode/min_svg_cache')
+let Resources = require('./Resources')
+let TextCache = require('@ndcode/text_cache')
+let ZipCache = require('@ndcode/zip_cache')
+let assert = require('assert')
+let fs = require('fs')
+let jst_server = require('./index')
+let util = require('util')
+
+let fs_mkdir = util.promisify(fs.mkdir)
+let fs_readFile = util.promisify(fs.readFile)
+let fs_stat = util.promisify(fs.stat)
+
+let Site = function(server, root) {
if (!this instanceof Site)
throw new Error('Site is a constructor')
this.server = server
this.socket_io_connect_listeners = [] // later will use this for destruction
+ this.root = root
+
+ this.json_cache = server.resources.ref(
+ 'json_cache',
+ () => new JSONCache(true)
+ )
+ this.json_cache_rw = server.resources.ref(
+ 'json_cache_rw',
+ () => new JSONCacheRW(true)
+ )
+ this.jst_cache = server.resources.ref(
+ `jst_cache:${root}`,
+ () => new JSTCache(root, {_jst_server: jst_server}, true)
+ )
+ this.less_css_cache = server.resources.ref(
+ `less_css_cache:${root}`,
+ () => new LessCSSCache(root, true)
+ )
+ this.min_css_cache = server.resources.ref(
+ 'min_css_cache',
+ () => new MinCSSCache(true)
+ )
+ this.min_js_cache = server.resources.ref(
+ 'min_js_cache',
+ () => new MinJSCache(true)
+ )
+ this.min_html_cache = server.resources.ref(
+ 'min_html_cache',
+ () => new MinHTMLCache(true)
+ )
+ this.min_svg_cache = server.resources.ref(
+ 'min_svg_cache',
+ () => new MinSVGCache(true)
+ )
+ this.text_cache = server.resources.ref(
+ 'text_cache',
+ () => new TextCache(true)
+ )
+ this.zip_cache = server.resources.ref(
+ 'zip_cache',
+ () => new ZipCache(true)
+ )
}
+Site.prototype = Object.create(Site.prototype)
+
Site.prototype.serve = function(env, status, data, message_from) {
this.server.serve(
env.response,
)
}
+Site.prototype.internal_ensure_dir = async function(pathname) {
+ try {
+ await fs_mkdir(pathname)
+ console.log('create directory', pathname)
+ }
+ catch (err) {
+ if (err.code !== 'EEXIST') // should check error type
+ throw err
+ }
+}
+
+Site.prototype.get_json = function(pathname) {
+ return /*await*/ this.json_cache.get(this.root + pathname)
+}
+
+Site.prototype.get_jst = function(pathname) {
+ return /*await*/ this.jst_cache.get(this.root + pathname)
+}
+
+Site.prototype.get_less_css = function(pathname) {
+ return /*await*/ this.less_css_cache.get(this.root + pathname)
+}
+
+Site.prototype.get_min_css = function(pathname) {
+ return /*await*/ this.min_css_cache.get(this.root + pathname)
+}
+
+Site.prototype.get_min_html = function(pathname) {
+ return /*await*/ this.min_html_cache.get(this.root + pathname)
+}
+
+Site.prototype.get_min_js = function(pathname) {
+ return /*await*/ this.min_js_cache.get(this.root + pathname)
+}
+
+Site.prototype.get_min_svg = function(pathname) {
+ return /*await*/ this.min_svg_cache.get(this.root + pathname)
+}
+
+Site.prototype.get_text = function(pathname) {
+ return /*await*/ this.text_cache.get(this.root + pathname)
+}
+
+Site.prototype.get_zip = function(pathname) {
+ return /*await*/ this.zip_cache.get(this.root + pathname)
+}
+
+Site.prototype.ensure_dir = async function(pathname) {
+ return /*await*/ this.internal_ensure_dir(this.root + pathname)
+}
+
+// this is for read/write JSON files
+// they will not be reloaded from disk if modified
+Site.prototype.read_json = async function(pathname, default_value) {
+ return /*await*/ this.json_cache_rw.read(
+ this.root + pathname,
+ default_value
+ )
+}
+
+Site.prototype.write_json = async function(pathname, value, timeout) {
+ return /*await*/ this.json_cache_rw.write(
+ this.root + pathname,
+ value,
+ timeout
+ )
+}
+
+Site.prototype.modify_json =
+ async function(pathname, default_value, modify_func, timeout) {
+ return /*await*/ this.json_cache_rw.modify(
+ this.root + pathname,
+ default_value,
+ modify_func,
+ timeout
+ )
+ }
+
+Site.prototype.serve_jst = async function(env, pathname, ...args) {
+ let template
+ try {
+ template = await this.jst_cache.get(pathname)
+ }
+ catch (err) {
+ if (!(err instanceof Error) || err.code !== 'ENOENT')
+ throw err
+ return false
+ }
+ env.site = this
+ await template(env, ...args)
+ return true
+}
+
+Site.prototype.serve_less_css = async function(env, pathname) {
+ if (pathname.slice(-9) !== '.css.less')
+ return false
+
+ let data
+ try {
+ data = await this.less_css_cache.get(pathname)
+ }
+ catch (err) {
+ if (!(err instanceof Error) || err.code !== 'ENOENT')
+ throw err
+ return false
+ }
+ this.serve(env, 200, data, 'less_css')
+ return true
+}
+
+Site.prototype.serve_min_css = async function(env, pathname) {
+ if (pathname.slice(-8) !== '.css.min')
+ return false
+
+ let data
+ try {
+ data = await this.min_css_cache.get(pathname)
+ }
+ catch (err) {
+ if (!(err instanceof Error) || err.code !== 'ENOENT')
+ throw err
+ return false
+ }
+ this.serve(env, 200, data, 'min_css')
+ return true
+}
+
+Site.prototype.serve_min_html = async function(env, pathname) {
+ if (pathname.slice(-9) !== '.html.min')
+ return false
+
+ let data
+ try {
+ data = await this.min_html_cache.get(pathname)
+ }
+ catch (err) {
+ if (!(err instanceof Error) || err.code !== 'ENOENT')
+ throw err
+ return false
+ }
+ this.serve(env, 200, data, 'min_html')
+ return true
+}
+
+Site.prototype.serve_min_js = async function(env, pathname) {
+ if (pathname.slice(-7) !== '.js.min')
+ return false
+
+ let data
+ try {
+ data = await this.min_js_cache.get(pathname)
+ }
+ catch (err) {
+ if (!(err instanceof Error) || err.code !== 'ENOENT')
+ throw err
+ return false
+ }
+ this.serve(env, 200, data, 'min_js')
+ return true
+}
+
+Site.prototype.serve_min_svg = async function(env, pathname) {
+ if (pathname.slice(-8) !== '.svg.min')
+ return false
+
+ let data
+ try {
+ data = await this.min_svg_cache.get(pathname)
+ }
+ catch (err) {
+ if (!(err instanceof Error) || err.code !== 'ENOENT')
+ throw err
+ return false
+ }
+ this.serve(env, 200, data, 'min_svg')
+ return true
+}
+
+Site.prototype.serve_fs = async function(env, pathname) {
+ let data
+ try {
+ data = await fs_readFile(pathname)
+ }
+ catch (err) {
+ if (!(err instanceof Error) || err.code !== 'ENOENT')
+ throw err
+ return false
+ }
+ this.serve(env, 200, data, 'fs')
+ return true
+}
+
+Site.prototype.serve_zip = async function(env, zipname, pathname) {
+ let zip
+ try {
+ zip = await this.zip_cache.get(zipname)
+ }
+ catch (err) {
+ if (!(err instanceof Error) || err.code !== 'ENOENT')
+ throw err
+ return false
+ }
+ if (!Object.prototype.hasOwnProperty.call(zip, pathname))
+ return false
+ this.serve(env, 200, zip[pathname], 'zip')
+ return true
+}
+
+Site.prototype.serve_file = async function(env, pathname) {
+ //console.log(`serve_file ${pathname}`)
+ if (await this.serve_jst(env, pathname + '.jst'))
+ return
+ if (await this.serve_less_css(env, pathname + '.less'))
+ return
+ if (await this.serve_min_css(env, pathname + '.min'))
+ return
+ if (await this.serve_min_html(env, pathname + '.min'))
+ return
+ if (await this.serve_min_js(env, pathname + '.min'))
+ return
+ if (await this.serve_min_svg(env, pathname + '.min'))
+ return
+ if (await this.serve_fs(env, pathname))
+ return
+ this.die(env, `file not found ${env.pathname}`)
+}
+
+Site.prototype.serve_dir = async function(env, pathname, components) {
+ if (await this.serve_jst(env, pathname + '.dir.jst', components))
+ return
+
+ let stats
+ try {
+ stats = await fs_stat(pathname)
+ }
+ catch (err) {
+ if (!(err instanceof Error) || err.code !== 'ENOENT')
+ throw err
+ this.die(env, `directory not found ${pathname}`)
+ return
+ }
+ if (!stats.isDirectory()) {
+ this.die(
+ env,
+ components.length > 1 ?
+ `not directory ${pathname}` :
+ `unknown extension "${extension}" in ${env.pathname}`
+ )
+ return
+ }
+ return /*await*/ this.serve_path(env, pathname, components)
+}
+
+Site.prototype.serve_path = async function(env, pathname, components) {
+ //console.log(`serve_path ${pathname} ${components}`)
+ if (components.length === 0) {
+ // directory without trailing slash
+ this.redirect(env, env.pathname + '/index.html')
+ return
+ }
+
+ if (components[0].length === 0) {
+ if (components.length > 1)
+ this.die(env, `empty directory name in ${env.pathname}`)
+ else
+ // directory with trailing slash
+ this.redirect(env, env.pathname + 'index.html')
+ return
+ }
+
+ if (
+ components[0].charAt(0) === '.' ||
+ components[0].charAt(0) === '_'
+ ) {
+ this.die(env, `bad component "${components[0]}" in ${env.pathname}`)
+ return
+ }
+
+ let i = components[0].lastIndexOf('.')
+ if (i === -1)
+ i = components[0].length
+ let extension = components[0].slice(i)
+
+ pathname = `${pathname}/${components[0]}`
+ if (
+ extension.length !== 0 &&
+ Object.prototype.hasOwnProperty.call(this.server.mime_types, extension)
+ ) {
+ if (components.length > 1) {
+ this.die(env, `non-directory extension "${extension}" in ${env.pathname}`)
+ return
+ }
+ return /*await*/ this.serve_file(env, pathname)
+ }
+ return /*await*/ this.serve_dir(env, pathname, components.slice(1))
+}
+
Site.prototype.respond = async function(env) {
- throw new Error('not implemented')
+ if (
+ await this.serve_zip(
+ env,
+ this.root + '/_favicon/favicons.zip',
+ env.pathname
+ )
+ )
+ return
+ let components = env.pathname.split('/')
+ if (components.length) {
+ assert(components[0].length == 0)
+ components = components.slice(1)
+ }
+ return /*await*/ this.serve_path(env, this.root, components)
}
module.exports = Site
+++ /dev/null
-let JSTCache = require('@ndcode/jst_cache')
-let Site = require('./Site')
-let jst_server = require('./index')
-
-let SiteConfig = function(server, root) {
- if (!this instanceof SiteConfig)
- throw new Error('SiteConfig is a constructor')
- Site.call(this, server)
- this.root = root
-
- this.resources_jst_cache = server.resources.ref(
- 'jst_cache',
- () => new Resources()
- )
- this.jst_cache = this.resources_jst_cache.ref(
- root,
- () => new JSTCache(root, {_jst_server: jst_server}, true)
- )
- this.site = undefined
-}
-
-SiteConfig.prototype = Object.create(Site.prototype)
-
-SiteConfig.prototype.respond = async function(env) {
- let config = await this.jst_cache.get(
- this.root + '/_config/site.jst',
- true
- )
- if (config !== undefined)
- this.site = await config(this.server, this.root, this.site)
- return this.site.respond(env)
-}
-
-module.exports = SiteConfig
+++ /dev/null
-let Site = require('./Site')
-
-let SiteRedirect = function(server, redirect) {
- if (!this instanceof SiteRedirect)
- throw new Error('SiteRedirect is a constructor')
- Site.call(this, server)
- this.redirect = redirect
-}
-
-SiteRedirect.prototype = Object.create(Site.prototype)
-
-SiteRedirect.respond = async function(env) {
- let new_host = this.redirect
- if (parsed_url.port !== undefined)
- new_host += ':' + parsed_url.port
- this.redirect(
- response,
- `${parsed_url.protocol}//${redirect}${request.url}`,
- `redirecting ${parsed_url.host} to ${new_host}`
- )
-}
-
-module.exports = SiteRedirect
+++ /dev/null
-let JSONCache = require('@ndcode/json_cache')
-let JSONCacheRW = require('@ndcode/json_cache_rw')
-let JSTCache = require('@ndcode/jst_cache')
-let LessCSSCache = require('@ndcode/less_css_cache')
-let MinCSSCache = require('@ndcode/min_css_cache')
-let MinJSCache = require('@ndcode/min_js_cache')
-let MinHTMLCache = require('@ndcode/min_html_cache')
-let MinSVGCache = require('@ndcode/min_svg_cache')
-let Resources = require('./Resources')
-let Site = require('./Site')
-let TextCache = require('@ndcode/text_cache')
-let ZipCache = require('@ndcode/zip_cache')
-let assert = require('assert')
-let fs = require('fs')
-let jst_server = require('./index')
-let util = require('util')
-
-let fs_mkdir = util.promisify(fs.mkdir)
-let fs_readFile = util.promisify(fs.readFile)
-let fs_stat = util.promisify(fs.stat)
-
-let SiteRoot = function(server, root) {
- if (!this instanceof SiteRoot)
- throw new Error('SiteRoot is a constructor')
- Site.call(this, server)
- this.root = root
-
- this.json_cache = new JSONCache(true)
- this.json_cache_rw = new JSONCacheRW(true)
- this.resources_jst_cache = server.resources.ref(
- 'jst_cache',
- () => new Resources()
- )
- this.jst_cache = server.resources_jst_cache.ref(
- root,
- () => new JSTCache(root, {_jst_server: jst_server}, true)
- )
- this.less_css_cache = new LessCSSCache(root, true)
- this.min_css_cache = new MinCSSCache(true)
- this.min_js_cache = new MinJSCache(true)
- this.min_html_cache = new MinHTMLCache(true)
- this.min_svg_cache = new MinSVGCache(true)
- this.text_cache = new TextCache(true)
- this.zip_cache = new ZipCache(true)
-}
-
-SiteRoot.prototype = Object.create(Site.prototype)
-
-SiteRoot.prototype.internal_ensure_dir = async function(pathname) {
- try {
- await fs_mkdir(pathname)
- console.log('create directory', pathname)
- }
- catch (err) {
- if (err.code !== 'EEXIST') // should check error type
- throw err
- }
-}
-
-SiteRoot.prototype.get_json = function(pathname) {
- return /*await*/ this.json_cache.get(this.root + pathname)
-}
-
-SiteRoot.prototype.get_jst = function(pathname) {
- return /*await*/ this.jst_cache.get(this.root + pathname)
-}
-
-SiteRoot.prototype.get_less_css = function(pathname) {
- return /*await*/ this.less_css_cache.get(this.root + pathname)
-}
-
-SiteRoot.prototype.get_min_css = function(pathname) {
- return /*await*/ this.min_css_cache.get(this.root + pathname)
-}
-
-SiteRoot.prototype.get_min_html = function(pathname) {
- return /*await*/ this.min_html_cache.get(this.root + pathname)
-}
-
-SiteRoot.prototype.get_min_js = function(pathname) {
- return /*await*/ this.min_js_cache.get(this.root + pathname)
-}
-
-SiteRoot.prototype.get_min_svg = function(pathname) {
- return /*await*/ this.min_svg_cache.get(this.root + pathname)
-}
-
-SiteRoot.prototype.get_text = function(pathname) {
- return /*await*/ this.text_cache.get(this.root + pathname)
-}
-
-SiteRoot.prototype.get_zip = function(pathname) {
- return /*await*/ this.zip_cache.get(this.root + pathname)
-}
-
-SiteRoot.prototype.ensure_dir = async function(pathname) {
- return /*await*/ this.internal_ensure_dir(this.root + pathname)
-}
-
-// this is for read/write JSON files
-// they will not be reloaded from disk if modified
-SiteRoot.prototype.read_json = async function(pathname, default_value) {
- return /*await*/ this.json_cache_rw.read(
- this.root + pathname,
- default_value
- )
-}
-
-SiteRoot.prototype.write_json = async function(pathname, value, timeout) {
- return /*await*/ this.json_cache_rw.write(
- this.root + pathname,
- value,
- timeout
- )
-}
-
-SiteRoot.prototype.modify_json =
- async function(pathname, default_value, modify_func, timeout) {
- return /*await*/ this.json_cache_rw.modify(
- this.root + pathname,
- default_value,
- modify_func,
- timeout
- )
- }
-
-SiteRoot.prototype.serve_jst = async function(env, pathname, ...args) {
- let template
- try {
- template = await this.jst_cache.get(pathname)
- }
- catch (err) {
- if (!(err instanceof Error) || err.code !== 'ENOENT')
- throw err
- return false
- }
- env.site = this
- await template(env, ...args)
- return true
-}
-
-SiteRoot.prototype.serve_less_css = async function(env, pathname) {
- if (pathname.slice(-9) !== '.css.less')
- return false
-
- let data
- try {
- data = await this.less_css_cache.get(pathname)
- }
- catch (err) {
- if (!(err instanceof Error) || err.code !== 'ENOENT')
- throw err
- return false
- }
- this.serve(env, 200, data, 'less_css')
- return true
-}
-
-SiteRoot.prototype.serve_min_css = async function(env, pathname) {
- if (pathname.slice(-8) !== '.css.min')
- return false
-
- let data
- try {
- data = await this.min_css_cache.get(pathname)
- }
- catch (err) {
- if (!(err instanceof Error) || err.code !== 'ENOENT')
- throw err
- return false
- }
- this.serve(env, 200, data, 'min_css')
- return true
-}
-
-SiteRoot.prototype.serve_min_html = async function(env, pathname) {
- if (pathname.slice(-9) !== '.html.min')
- return false
-
- let data
- try {
- data = await this.min_html_cache.get(pathname)
- }
- catch (err) {
- if (!(err instanceof Error) || err.code !== 'ENOENT')
- throw err
- return false
- }
- this.serve(env, 200, data, 'min_html')
- return true
-}
-
-SiteRoot.prototype.serve_min_js = async function(env, pathname) {
- if (pathname.slice(-7) !== '.js.min')
- return false
-
- let data
- try {
- data = await this.min_js_cache.get(pathname)
- }
- catch (err) {
- if (!(err instanceof Error) || err.code !== 'ENOENT')
- throw err
- return false
- }
- this.serve(env, 200, data, 'min_js')
- return true
-}
-
-SiteRoot.prototype.serve_min_svg = async function(env, pathname) {
- if (pathname.slice(-8) !== '.svg.min')
- return false
-
- let data
- try {
- data = await this.min_svg_cache.get(pathname)
- }
- catch (err) {
- if (!(err instanceof Error) || err.code !== 'ENOENT')
- throw err
- return false
- }
- this.serve(env, 200, data, 'min_svg')
- return true
-}
-
-SiteRoot.prototype.serve_fs = async function(env, pathname) {
- let data
- try {
- data = await fs_readFile(pathname)
- }
- catch (err) {
- if (!(err instanceof Error) || err.code !== 'ENOENT')
- throw err
- return false
- }
- this.serve(env, 200, data, 'fs')
- return true
-}
-
-SiteRoot.prototype.serve_zip = async function(env, zipname, pathname) {
- let zip
- try {
- zip = await this.zip_cache.get(zipname)
- }
- catch (err) {
- if (!(err instanceof Error) || err.code !== 'ENOENT')
- throw err
- return false
- }
- if (!Object.prototype.hasOwnProperty.call(zip, pathname))
- return false
- this.serve(env, 200, zip[pathname], 'zip')
- return true
-}
-
-SiteRoot.prototype.serve_file = async function(env, pathname) {
- //console.log(`serve_file ${pathname}`)
- if (await this.serve_jst(env, pathname + '.jst'))
- return
- if (await this.serve_less_css(env, pathname + '.less'))
- return
- if (await this.serve_min_css(env, pathname + '.min'))
- return
- if (await this.serve_min_html(env, pathname + '.min'))
- return
- if (await this.serve_min_js(env, pathname + '.min'))
- return
- if (await this.serve_min_svg(env, pathname + '.min'))
- return
- if (await this.serve_fs(env, pathname))
- return
- this.die(env, `file not found ${env.pathname}`)
-}
-
-SiteRoot.prototype.serve_dir = async function(env, pathname, components) {
- if (await this.serve_jst(env, pathname + '.dir.jst', components))
- return
-
- let stats
- try {
- stats = await fs_stat(pathname)
- }
- catch (err) {
- if (!(err instanceof Error) || err.code !== 'ENOENT')
- throw err
- this.die(env, `directory not found ${pathname}`)
- return
- }
- if (!stats.isDirectory()) {
- this.die(
- env,
- components.length > 1 ?
- `not directory ${pathname}` :
- `unknown extension "${extension}" in ${env.pathname}`
- )
- return
- }
- return /*await*/ this.serve_path(env, pathname, components)
-}
-
-SiteRoot.prototype.serve_path = async function(env, pathname, components) {
- //console.log(`serve_path ${pathname} ${components}`)
- if (components.length === 0) {
- // directory without trailing slash
- this.redirect(env, env.pathname + '/index.html')
- return
- }
-
- if (components[0].length === 0) {
- if (components.length > 1)
- this.die(env, `empty directory name in ${env.pathname}`)
- else
- // directory with trailing slash
- this.redirect(env, env.pathname + 'index.html')
- return
- }
-
- if (
- components[0].charAt(0) === '.' ||
- components[0].charAt(0) === '_'
- ) {
- this.die(env, `bad component "${components[0]}" in ${env.pathname}`)
- return
- }
-
- let i = components[0].lastIndexOf('.')
- if (i === -1)
- i = components[0].length
- let extension = components[0].slice(i)
-
- pathname = `${pathname}/${components[0]}`
- if (
- extension.length !== 0 &&
- Object.prototype.hasOwnProperty.call(this.server.mime_types, extension)
- ) {
- if (components.length > 1) {
- this.die(env, `non-directory extension "${extension}" in ${env.pathname}`)
- return
- }
- return /*await*/ this.serve_file(env, pathname)
- }
- return /*await*/ this.serve_dir(env, pathname, components.slice(1))
-}
-
-SiteRoot.prototype.respond = async function(env) {
- if (
- await this.serve_zip(
- env,
- this.root + '/_favicon/favicons.zip',
- env.pathname
- )
- )
- return
- let components = env.pathname.split('/')
- if (components.length) {
- assert(components[0].length == 0)
- components = components.slice(1)
- }
- return /*await*/ this.serve_path(env, this.root, components)
-}
-
-module.exports = SiteRoot
{
"enable_caching": false,
"listen": [
- {"port": 8080},
- {"port": 8443, "protocol": "https:"}
+ {
+ "port": 8080
+ },
+ {
+ "port": 8443,
+ "protocol": "https:"
+ }
],
"mime_types": {
".css": "text/css; charset=utf-8",
".svg": "image/svg+xml",
".xml": "text/xml; charset=utf-8"
},
- sites: {
- 'localhost': new _jst_server.SiteRoot(server, 'site'),
- 'localhost.localdomain': new _jst_server.SiteRedirect(server, 'localhost')
+ hosts: {
+ "localhost": {
+ "type": "site",
+ "root": "site"
+ },
+ "localhost.localdomain": {
+ "type": "redirect",
+ "host": "localhost"
+ }
}
}
)
#!/usr/bin/env node
+// must load index first, to avoid circular dependency issue
+let index = require('./index')
let Server = require('./Server')
let server = new Server()
exports.Resources = require('./Resources')
exports.Server = require('./Server')
exports.Site = require('./Site')
-exports.SiteConfig = require('./SiteConfig')
-exports.SiteRedirect = require('./SiteRedirect')
-exports.SiteRoot = require('./SiteRoot')
"author": "Nick Downing",
"license": "GPL-3.0",
"bin": {
- "jst_server": "jst_server.js"
+ "jst_server": "cli.js"
}
}
--- /dev/null
+return async (server, root, prev_site) => new _jst_server.Site(server, root)