Last active
March 13, 2019 17:38
-
-
Save Jimbly/d996bd8c80ae1a376a0b to your computer and use it in GitHub Desktop.
Revisions
-
Jimbly revised this gist
Nov 29, 2014 . 1 changed file with 4 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,7 @@ // Companion Blog Post about architecture: // http://jimbesser.wordpress.com/2014/10/20/its-node-js-all-the-way-down/ // Companion Blog Post about dealing with legacy requests: // http://jimbesser.wordpress.com/2014/11/29/the-horrible-things-peoples-routers-do-to-my-packets/ // // Routing handled by this app: // [www.]bigscreensmallgames.com -> static site: /var/data/smb_web/bigscreensmallgames.com/ -
Jimbly revised this gist
Nov 29, 2014 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,5 @@ // Companion Blog Post about architecture: http://jimbesser.wordpress.com/2014/10/20/its-node-js-all-the-way-down/ // Companion Blog Post about dealing with legacy requests: http://jimbesser.wordpress.com/2014/11/29/the-horrible-things-peoples-routers-do-to-my-packets/ // // Routing handled by this app: // [www.]bigscreensmallgames.com -> static site: /var/data/smb_web/bigscreensmallgames.com/ -
Jimbly revised this gist
Oct 21, 2014 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,6 @@ // Companion Blog Post: http://jimbesser.wordpress.com/2014/10/20/its-node-js-all-the-way-down/ // // Routing handled by this app: // [www.]bigscreensmallgames.com -> static site: /var/data/smb_web/bigscreensmallgames.com/ // fanime.info -> node app running entire site on port 4001 // [default site]/app1: replace URL and redirect to single page app on 192.168.0.127:21022 -
Jimbly revised this gist
Oct 11, 2014 . 1 changed file with 19 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -31,13 +31,14 @@ function openNewLogFile() { openNewLogFile(); setInterval(openNewLogFile, 12*60*60*1000); function handleError(e) { log('ERROR: ' + (e.stack || e)); console.error('ERROR', new Date(), e); } // Absolutely required, httpProxy throws uncaught socket hang-up exceptions // whenever proxying to another server which disconnects a socket (e.g. if you // you make a socket.io connection to the wrong endpoint). process.on('uncaughtException', handleError); function staticSite(app, dir) { app = app || express(); @@ -109,7 +110,19 @@ vhost_app.use(main); vhost_ws.use(main_ws); var server = http.createServer(function (req, res) { // Re-map a url with a host into the format express/vhost logic needs if (!req.headers.host && req.url.indexOf('://') !== -1) { log('Remapping legacy request with no host for ' + req.url); var parsed = url.parse(req.url); req.headers.host = parsed.host; req.url = parsed.path + (parsed.hash || ''); } // Need to attach this error handler because morgan implicitly adds an error // handler which squashes this error from ever being seen! req.socket.on('error', handleError); vhost_app(req, res); }); server.on('upgrade', function (req, socket, head) { // Use the same express.Router logic for vhost mapping of the upgrade request vhost_ws(req, { socket: socket, head: head }, function () { -
Jimbly revised this gist
Oct 11, 2014 . 1 changed file with 1 addition and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,6 @@ // [www.]bigscreensmallgames.com -> static site: /var/data/smb_web/bigscreensmallgames.com/ // fanime.info -> node app running entire site on port 4001 // [default site]/app1: replace URL and redirect to single page app on 192.168.0.127:21022 // [default site] -> static site: /var/data/smb_web/dashingstrike.com/ var express = require('express'); -
Jimbly created this gist
Oct 11, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,157 @@ // [www.]bigscreensmallgames.com -> static site: /var/data/smb_web/bigscreensmallgames.com/ // fanime.info -> node app running entire site on port 4001 // [default site]/app1: replace URL and redirect to single page app on port 4002 // [default site] -> static site: /var/data/smb_web/dashingstrike.com/ var express = require('express'); var fs = require('fs'); var http = require('http'); var httpProxy = require('http-proxy'); var morgan = require('morgan'); var serveIndex = require('serve-index'); var serveStatic = require('serve-static'); var through = require('through'); var vhost = require('vhost'); var out_stream = through(); out_stream.pipe(process.stdout); function log(msg) { out_stream.write('**LOG: ' + new Date().toISOString() + ' ' + msg + '\n'); } var last_log_file; function openNewLogFile() { var filename = '/var/log/webroot.' + new Date().toISOString().slice(0, 13).replace(/\:/g, '_').replace('T', '_') + '.log'; last_log_file && last_log_file.close(); last_log_file = fs.createWriteStream(filename, { flags: 'a', mode: 0664 }); out_stream.pipe(last_log_file); log('Opened new log file: ' + filename); } openNewLogFile(); setInterval(openNewLogFile, 12*60*60*1000); process.on('uncaughtException', function (e) { // Absolutely required, httpProxy throws uncaught socket hang-up exceptions // whenever proxying to another server which disconnects a socket (e.g. if you // you make a socket.io connection to the wrong endpoint). log('ERROR: ' + (e.stack || e)); console.error('ERROR', new Date(), e); }); function staticSite(app, dir) { app = app || express(); app.use(serveStatic('/var/data/smb_web/' + dir + '/')); app.use(serveIndex('/var/data/smb_web/' + dir + '/', { icons: true, view: 'details' })); return app; } function wsProxy(proxy) { return function (req, data) { log('Proxying ws upgrade request for ' + req.headers.host + ' ' + (req.originalUrl || req.url)); proxy.ws(req, data.socket, data.head); }; } function webProxy(proxy) { return proxy.web.bind(proxy); } function directoryize(app, dir) { // redirect requests for /foo to /foo/ so that relative paths don't get messed up app.get('/' + dir, function (req, res, next) { if (req.url !== '/' + dir) { return next(); } res.redirect('/' + dir + '/'); }); } // Sub sites running as separate processes var proxy_fanimeinfo = httpProxy.createProxyServer({ target: { host: 'localhost', port: 4001 }, agent: http.globalAgent, // passing agent to prevent connection: close from being added xfwd: true, // add x-forwarded-for header so we get the real IP }); var proxy_app1 = httpProxy.createProxyServer({ target: { host: '192.168.0.127', port: 21022 }, agent: http.globalAgent, // passing agent to prevent connection: close from being added xfwd: true, // add x-forwarded-for header so we get the real IP }); var main = express(); var main_ws = express.Router(); directoryize(main, 'app1'); main.use('/app1', webProxy(proxy_app1)); main_ws.use('/app1', wsProxy(proxy_app1)); staticSite(main, 'dashingstrike.com'); // Root vhost app var vhost_app = express(); var vhost_ws = express.Router(); // Logging vhost_app.use(morgan(':remote-addr [:date] ":method :req[host]:url" START ":referrer" ":user-agent"', { stream: out_stream })); vhost_app.use(morgan(':remote-addr [:date] ":method :req[host]:url" FINISH :status :res[content-length] :response-time ms', { stream: out_stream })); // Directory mapped virtual hosts vhost_app.use(vhost(/(?:www\.)?bigscreensmallgames\.com/, staticSite(null, 'bigscreensmallgames.com'))); // Virtual hosts mapping to other node apps running as separate processes vhost_app.use(vhost(/(?:www\.)?fanime\.info/, webProxy(proxy_fanimeinfo))); vhost_ws.use(vhost(/(?:www\.)?fanime\.info/, wsProxy(proxy_fanimeinfo))); // Default - dashingstrike.com and variants, anything unknown, etc vhost_app.use(main); vhost_ws.use(main_ws); var server = http.createServer(vhost_app); server.on('upgrade', function (req, socket, head) { // Use the same express.Router logic for vhost mapping of the upgrade request vhost_ws(req, { socket: socket, head: head }, function () { log('No one to proxy websocket to for ' + req.headers.host + ' ' + req.url); }); }); // Add intercept to remove null-termination from requests from libGlov's fetch.cpp server.on('connection', function (s) { var orig_ondata = s.ondata; var is_legacy = false; var call_count = 0; s.ondata = function (d, start, end) { ++call_count; if (call_count === 1) { var head = d.slice(start, Math.min(end, start + 11)).toString(); is_legacy = (head === 'GET http://'); if (is_legacy && d.slice(end-2, end).toString()==='\n\0') { // Remove null termination that will cause a HTTP parser error log('Stripping null from null terimianted request buffer'); end = end - 1; s.ondata = orig_ondata; // Remove hook } } else if (call_count === 2) { // assert.ok(is_legacy); if (end - start <= 2 && d[end-1] === 0) { log('Stripping null from now empty request buffer'); end = end - 1; } s.ondata = orig_ondata; // Remove hook } if (!is_legacy) { s.ondata = orig_ondata; // Remove hook } orig_ondata(d, start, end); }; }); // I gave the node binary privileges to listen on this port by running: // $ sudo setcap cap_net_bind_service=+ep `which node` var port = 80; server.listen(port); log('Started webroot on port ' + port + ', process id ' + process.pid);