Make Server an object, hence easier to access server.caching, server.die() etc
authorNick Downing <downing.nick@gmail.com>
Sun, 21 Oct 2018 01:08:37 +0000 (12:08 +1100)
committerNick Downing <downing.nick@gmail.com>
Sun, 21 Oct 2018 01:08:37 +0000 (12:08 +1100)
Server.js [moved from server.js with 71% similarity]
Site.js
jst_server.js

similarity index 71%
rename from server.js
rename to Server.js
index 73864c5..a967262 100644 (file)
--- a/server.js
+++ b/Server.js
@@ -4,38 +4,39 @@ let config = require('./config')
 let js_template = require('js_template')
 let url = require('url')
 
-let caching = false
-let set_caching = value => {
-  caching = value
+let Server = function(caching) {
+  if (!this instanceof Server)
+    throw Error('Server is a constructor')
+  this.caching = caching || false
+  this.site_cache = {}
 }
 
-let serve = (response, status, mime_type, data) => {
+Server.prototype.serve = function(response, status, mime_type, data) {
   response.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
   // and won't change frequently (but we'll need cache busting eventually)
-  if (caching && mime_type !== config.mime_types_html)
+  if (this.caching && mime_type !== config.mime_types_html)
     response.setHeader('Cache-Control', 'max-age=3600')
   response.setHeader('Content-Type', mime_type)
   response.setHeader('Content-Length', data.length)
   response.end(data)
 }
 
-let die = response => {
+Server.prototype.die = function(response) {
   let body = '<html><body>Page not found</body></html>'
-  serve(response, 404, config.mime_type_html, Buffer.from(body))
+  this.serve(response, 404, config.mime_type_html, Buffer.from(body))
 }
 
-let redirect = (response, location) => {
+Server.prototype.redirect = function(response, location) {
   response.statusCode = 301
   response.setHeader('Location', location)
   response.end('Redirecting to ' + location)
 }
 
-let site_cache = {}
 let site_factory_default = async root => new Site(root)
 
-let respond = async (request, response, protocol) => {
+Server.prototype.respond = async function(request, response, protocol) {
   try {
     await config.refresh()
     let parsed_url = url.parse(
@@ -46,7 +47,7 @@ let respond = async (request, response, protocol) => {
 
     if (!Object.prototype.hasOwnProperty.call(config.sites, parsed_url.hostname)) {
       console.log('nonexistent site', parsed_url.hostname)
-      die(response)
+      this.die(response)
       return
     }
     let temp = config.sites[parsed_url.hostname]
@@ -56,7 +57,7 @@ let respond = async (request, response, protocol) => {
       if (parsed_url.port !== undefined)
         hostname += ':' + parsed_url.port
       console.log('redirecting', parsed_url.host, 'to', hostname)
-      redirect(response, parsed_url.protocol + '//' + hostname + request.url)
+      this.redirect(response, parsed_url.protocol + '//' + hostname + request.url)
       break
     case 'site':
       let site_factory
@@ -74,14 +75,14 @@ let respond = async (request, response, protocol) => {
       }
       let site
       if (
-        !Object.prototype.hasOwnProperty.call(site_cache, temp.root) ||
-        (site = site_cache[temp.root]).factory !== site_factory
+        !Object.prototype.hasOwnProperty.call(this.site_cache, temp.root) ||
+        (site = this.site_cache[temp.root]).factory !== site_factory
       ) {
         site = {
           factory: site_factory,
           object: await site_factory(temp.root)
         }
-        site_cache[temp.root] = site
+        this.site_cache[temp.root] = site
       }
       await site.object.respond(
         {
@@ -90,6 +91,7 @@ let respond = async (request, response, protocol) => {
           pathname_pos: 0,
           response: response,
           request: request,
+          server: this,
           site: site.object
         }
       )
@@ -102,12 +104,8 @@ let respond = async (request, response, protocol) => {
     let message = (err.stack || err.message).toString()
     console.error(message)
     let body = '<html><body><pre>' + message + '</pre></body></html>'
-    serve(response, 500, config.mime_type_html, Buffer.from(body, 'utf8'))
+    this.serve(response, 500, config.mime_type_html, Buffer.from(body, 'utf8'))
   }
 }
 
-exports.set_caching = set_caching
-exports.serve = serve
-exports.die = die
-exports.redirect = redirect
-exports.respond = respond
+module.exports = Server
diff --git a/Site.js b/Site.js
index a1709a2..c9e1858 100644 (file)
--- a/Site.js
+++ b/Site.js
@@ -8,7 +8,6 @@ let fs = require('fs')
 let js_template = require('js_template')
 let less = require('less/lib/less-node')
 let resources = require('./resources')
-let server = require('./server')
 var stream_buffers = require('stream-buffers')
 let util = require('util')
 let url = require('url')
@@ -32,7 +31,7 @@ Site.prototype.get_email = function(path) {
     path,
     async result => {
       console.log('getting', path, 'as email')
-      result.value = emailjs.server.connect(
+      result.value = emailjs.env.server.connect(
         JSON.parse(await fs_readFile(path))
       )
     }
@@ -209,7 +208,7 @@ Site.prototype.serve_jst = async function(env, pathname) {
   console.log(
     `${env.parsed_url.host} serving ${env.pathname} length ${data.length} from jst`
   )
-  server.serve(env.response, 200, mime_type, data)
+  env.server.serve(env.response, 200, mime_type, data)
   return true
 }
 
@@ -229,7 +228,7 @@ Site.prototype.serve_less = async function(env, pathname) {
   console.log(
     `${env.parsed_url.host} serving ${env.pathname} length ${data.length} from less`
   )
-  server.serve(env.response, 200, config.mime_types['.css'], data)
+  env.server.serve(env.response, 200, config.mime_types['.css'], data)
   return true
 }
 
@@ -247,7 +246,7 @@ Site.prototype.serve_fs = async function(env, pathname) {
     `${env.parsed_url.host} serving ${env.pathname} length ${data.length} from fs`
   )
   let filetype = env.pathname.slice(env.pathname_pos)
-  server.serve(env.response, 200, config.mime_types[filetype], data)
+  env.server.serve(env.response, 200, config.mime_types[filetype], data)
   return true
 }
 
@@ -269,7 +268,7 @@ Site.prototype.serve_zip = async function(env, pathname) {
     `${env.parsed_url.host} serving ${env.pathname} length ${data.length} from zip`
   )
   let filetype = env.pathname.slice(env.pathname_pos)
-  server.serve(env.response, 200, config.mime_types[filetype], data)
+  env.server.serve(env.response, 200, config.mime_types[filetype], data)
   return true
 }
 
@@ -280,7 +279,7 @@ Site.prototype.respond = async function(env) {
       console.log(
         `${env.parsed_url.host} redirecting ${env.pathname} to ${pathname}`
       )
-      server.redirect(
+      env.server.redirect(
         env.response,
         pathname + (env.parsed_url.search || '')
       )
@@ -300,7 +299,7 @@ Site.prototype.respond = async function(env) {
         console.log(
           `${env.parsed_url.host} redirecting ${env.pathname} to ${pathname}`
         )
-        server.redirect(
+        env.server.redirect(
           env.response,
           pathname + (env.parsed_url.search || '')
         )
@@ -309,7 +308,7 @@ Site.prototype.respond = async function(env) {
         console.log(
           `${env.parsed_url.host} empty directory name in ${env.pathname}`
         )
-        server.die(env.response)
+        env.server.die(env.response)
       }
       return
     }
@@ -321,7 +320,7 @@ Site.prototype.respond = async function(env) {
       console.log(
         `${env.parsed_url.host} bad component "${filename}" in ${env.pathname}`
       )
-      server.die(env.response)
+      env.server.die(env.response)
       return
     }
 
@@ -338,7 +337,7 @@ Site.prototype.respond = async function(env) {
         console.log(
           `${env.parsed_url.host} non-directory filetype "${filetype}" in ${env.pathname}`
         )
-        server.die(env.response)
+        env.server.die(env.response)
         return
       }
       env.pathname_pos = i + k // advance to "." at start of filetype
@@ -360,14 +359,14 @@ Site.prototype.respond = async function(env) {
       console.log(
         `${env.parsed_url.host} directory not found: ${pathname}`
       )
-      server.die(env.response)
+      env.server.die(env.response)
       return
     }
     if (!stats.isDirectory()) {
       console.log(
         `${env.parsed_url.host} not directory: ${pathname}`
       )
-      server.die(env.response)
+      env.server.die(env.response)
       return
     }
   }    
@@ -381,7 +380,7 @@ Site.prototype.respond = async function(env) {
     console.log(
       `${env.parsed_url.host} file not found ${env.pathname}`
     )
-    server.die(env.response)
+    env.server.die(env.response)
   }
 }
 
index 6078319..c9c79e1 100755 (executable)
@@ -1,10 +1,10 @@
 #!/usr/bin/env node
 
+let Server = require('./Server')
 let commander = require('commander')
 let fs = require('fs')
 let http = require('http')
 let https = require('https')
-let server = require('./server')
 
 commander.version('1.0.0').option(
   '-c, --enable-caching',
@@ -27,22 +27,24 @@ commander.version('1.0.0').option(
   8443
 ).parse(process.argv)
 
-server.set_caching(commander.enableCaching)
+let server = new Server(commander.enableCaching)
 if (commander.httpPort !== -1) {
-  http.createServer(
+  let http_server = http.createServer(
     (request, response) =>
       server.respond(request, response, 'http:') // ignore returned promise
-  ).listen(commander.httpPort)
+  )
+  http_server.listen(commander.httpPort)
   console.log('HTTP server listening on port', commander.httpPort)
 }
 if (commander.httpsPort !== -1) {
-  https.createServer(
+  let https_server = https.createServer(
     {
       'cert': fs.readFileSync(commander.sslCert),
       'key': fs.readFileSync(commander.sslKey)
     },
     (request, response) =>
       server.respond(request, response, 'https:') // ignore returned promise
-  ).listen(commander.httpsPort)
+  )
+  https_server.listen(commander.httpsPort)
   console.log('HTTPS server listening on port', commander.httpsPort)
 }