load apps from DB
This commit is contained in:
parent
1bb21f5a07
commit
65645a7602
|
@ -6,6 +6,8 @@ dyndns-token.js
|
|||
vhosts
|
||||
certs
|
||||
.*.sw*
|
||||
packages
|
||||
var
|
||||
|
||||
# Logs
|
||||
logs
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
'use strict';
|
||||
|
||||
// TODO handle static app urls?
|
||||
// NOTE rejecting non-api urls should happen before this
|
||||
module.exports.create = function (conf, deps, app) {
|
||||
var escapeStringRegexp = require('escape-string-regexp');
|
||||
var vhostsMap = conf.vhostsMap;
|
||||
if (!app) {
|
||||
app = deps.app;
|
||||
}
|
||||
|
||||
function getApi(route) {
|
||||
// TODO don't modify route, modify some other variable instead
|
||||
|
||||
var PromiseA = require('bluebird');
|
||||
var path = require('path');
|
||||
console.log(route);
|
||||
// TODO needs some version stuff (which would also allow hot-loading of updates)
|
||||
// TODO version could be tied to sha256sum
|
||||
var pkgpath = path.join(conf.apipath, (route.api.package || route.api.id), (route.api.version || ''));
|
||||
|
||||
console.log('pkgpath');
|
||||
console.log(pkgpath);
|
||||
|
||||
return new PromiseA(function (resolve, reject) {
|
||||
try {
|
||||
route.route = require(pkgpath).create(conf, deps.app, app);
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(route.route);
|
||||
});
|
||||
}
|
||||
|
||||
function api(req, res, next) {
|
||||
var apps;
|
||||
|
||||
console.log('hostname', req.hostname);
|
||||
console.log('headers', req.headers);
|
||||
|
||||
if (!vhostsMap[req.hostname]) {
|
||||
// TODO keep track of match-only vhosts, such as '*.example.com',
|
||||
// separate from exact matches
|
||||
next(new Error("this domain is not registered"));
|
||||
return;
|
||||
}
|
||||
|
||||
vhostsMap[req.hostname].pathnames.some(function (route) {
|
||||
var pathname = route.pathname;
|
||||
if ('/' === pathname) {
|
||||
pathname = '/api';
|
||||
}
|
||||
if (-1 === pathname.indexOf('/api')) {
|
||||
pathname = '/api' + pathname;
|
||||
}
|
||||
|
||||
if (!route.re) {
|
||||
route.re = new RegExp(escapeStringRegexp(pathname) + '(#|\\/|\\?|$)');
|
||||
}
|
||||
// re.test("/api")
|
||||
// re.test("/api?")
|
||||
// re.test("/api/")
|
||||
// re.test("/api/foo")
|
||||
// re.test("/apifoo") // false
|
||||
if (route.re.test(req.url)) {
|
||||
apps = route.apps;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!apps) {
|
||||
console.log('No apps to try for this hostname');
|
||||
console.log(vhostsMap[req.hostname]);
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
//console.log(apps);
|
||||
|
||||
function nextify(err) {
|
||||
var route;
|
||||
|
||||
if (err) {
|
||||
next(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// shortest to longest
|
||||
//route = apps.pop();
|
||||
// longest to shortest
|
||||
route = apps.shift();
|
||||
if (!route) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (route.route) {
|
||||
route.route(req, res, nextify);
|
||||
return;
|
||||
}
|
||||
|
||||
if (route._errored) {
|
||||
nextify(new Error("couldn't load api"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!route.api) {
|
||||
nextify(new Error("no api available for this route"));
|
||||
return;
|
||||
}
|
||||
|
||||
getApi(route).then(function (route) {
|
||||
try {
|
||||
route(req, res, nextify);
|
||||
route.route = route;
|
||||
} catch(e) {
|
||||
route._errored = true;
|
||||
console.error('[App Load Error]');
|
||||
console.error(e.stack);
|
||||
nextify(new Error("couldn't load api"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
nextify();
|
||||
}
|
||||
|
||||
return {
|
||||
api: api
|
||||
};
|
||||
};
|
|
@ -12,8 +12,12 @@ module.exports.create = function (securePort, insecurePort, redirects) {
|
|||
var host = req.headers.host || '';
|
||||
var url = req.url;
|
||||
|
||||
if (require('./unbrick-appcache').unbrick(req, res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// because I have domains for which I don't want to pay for SSL certs
|
||||
insecureRedirects = redirects.sort(function (a, b) {
|
||||
insecureRedirects = (redirects||[]).sort(function (a, b) {
|
||||
var hlen = b.from.hostname.length - a.from.hostname.length;
|
||||
var plen;
|
||||
if (!hlen) {
|
||||
|
|
|
@ -13,12 +13,20 @@ module.exports.create = function (certPaths, port, serverCallback) {
|
|||
}
|
||||
|
||||
server.on('error', serverCallback);
|
||||
server.listen(port, function () {
|
||||
server.listen(port, '0.0.0.0', function () {
|
||||
// is it even theoritically possible for
|
||||
// a request to come in before this callback has fired?
|
||||
// I'm assuming this event must fire before any request event
|
||||
promiseApp = serverCallback(null, server);
|
||||
});
|
||||
/*
|
||||
server.listen(port, '::::', function () {
|
||||
// is it even theoritically possible for
|
||||
// a request to come in before this callback has fired?
|
||||
// I'm assuming this event must fire before any request event
|
||||
promiseApp = serverCallback(null, server);
|
||||
});
|
||||
*/
|
||||
|
||||
// Get up and listening as absolutely quickly as possible
|
||||
server.on('request', function (req, res) {
|
||||
|
@ -29,6 +37,7 @@ module.exports.create = function (certPaths, port, serverCallback) {
|
|||
}
|
||||
|
||||
promiseApp.then(function (_app) {
|
||||
console.log('[Server]', req.method, req.host || req.headers['x-forwarded-host'] || req.headers.host, req.url);
|
||||
app = _app;
|
||||
app(req, res);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
module.exports.scrubTheDub = function (req, res) {
|
||||
// hack for bricked app-cache
|
||||
// Also 301 redirects will not work for appcache (must issue html)
|
||||
if (require('./unbrick-appcache').unbrick(req, res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO port number for non-443
|
||||
var escapeHtml = require('escape-html');
|
||||
var newLocation = 'https://' + req.hostname.replace(/^www\./, '') + req.url;
|
||||
var safeLocation = escapeHtml(newLocation);
|
||||
|
||||
var metaRedirect = ''
|
||||
+ '<html>\n'
|
||||
+ '<head>\n'
|
||||
+ ' <style>* { background-color: white; color: white; text-decoration: none; }</style>\n'
|
||||
+ ' <META http-equiv="refresh" content="0;URL=' + safeLocation + '">\n'
|
||||
+ '</head>\n'
|
||||
+ '<body style="display: none;">\n'
|
||||
+ ' <p>You requested an old resource. Please use this instead: \n'
|
||||
+ ' <a href="' + safeLocation + '">' + safeLocation + '</a></p>\n'
|
||||
+ '</body>\n'
|
||||
+ '</html>\n'
|
||||
;
|
||||
|
||||
res.end(metaRedirect);
|
||||
};
|
|
@ -1,5 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
var getDomainInfo = require('../lib/utils').getDomainInfo;
|
||||
|
||||
function deserialize(results) {
|
||||
var config = { apis: {}, apps: {}, domains: {} };
|
||||
results.apis.forEach(function (api) {
|
||||
|
@ -70,7 +72,62 @@ function deserialize(results) {
|
|||
return config;
|
||||
}
|
||||
|
||||
function getVhostsMap(config) {
|
||||
var vhosts = [];
|
||||
var vhostsMap = {};
|
||||
|
||||
function sortApps(a, b) {
|
||||
// hlen isn't important in this current use of the sorter,
|
||||
// but is important for an alternate version
|
||||
var hlen = b.hostname.length - a.hostname.length;
|
||||
var plen = b.pathname.length - a.pathname.length;
|
||||
|
||||
// A directory could be named example.com, example.com# example.com##
|
||||
// to indicate order of preference (for API addons, for example)
|
||||
var dlen = (b.priority || b.dirname.length) - (a.priority || a.dirname.length);
|
||||
|
||||
if (!hlen) {
|
||||
if (!plen) {
|
||||
return dlen;
|
||||
}
|
||||
return plen;
|
||||
}
|
||||
return hlen;
|
||||
}
|
||||
|
||||
Object.keys(config.domains).forEach(function (domainname) {
|
||||
var domain = config.domains[domainname];
|
||||
var info = getDomainInfo(domainname);
|
||||
|
||||
domain.hostname = info.hostname;
|
||||
domain.pathname = '/' + (info.pathname || '');
|
||||
domain.dirname = info.dirname;
|
||||
|
||||
vhosts.push(domain);
|
||||
});
|
||||
|
||||
vhosts.sort(sortApps);
|
||||
|
||||
vhosts.forEach(function (domain) {
|
||||
console.log(domain.hostname, domain.pathname, domain.dirname);
|
||||
|
||||
if (!vhostsMap[domain.hostname]) {
|
||||
vhostsMap[domain.hostname] = { pathnamesMap: {}, pathnames: [] };
|
||||
}
|
||||
|
||||
if (!vhostsMap[domain.hostname].pathnamesMap[domain.pathname]) {
|
||||
vhostsMap[domain.hostname].pathnamesMap[domain.pathname] = { pathname: domain.pathname, apps: [] };
|
||||
vhostsMap[domain.hostname].pathnames.push(vhostsMap[domain.hostname].pathnamesMap[domain.pathname]);
|
||||
}
|
||||
|
||||
vhostsMap[domain.hostname].pathnamesMap[domain.pathname].apps.push(domain);
|
||||
});
|
||||
|
||||
return vhostsMap;
|
||||
}
|
||||
|
||||
module.exports.deserialize = deserialize;
|
||||
module.exports.getVhostsMap = getVhostsMap;
|
||||
module.exports.create = function (db) {
|
||||
console.log('[DB -1]');
|
||||
var wrap = require('dbwrap');
|
||||
|
@ -162,9 +219,7 @@ module.exports.create = function (db) {
|
|||
// create fixture with which to test
|
||||
// console.log(JSON.stringify(results));
|
||||
|
||||
var config = deserialize(results);
|
||||
|
||||
return config;
|
||||
return getVhostsMap(deserialize(results));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -20,8 +20,12 @@ function tplCaddyfile(conf) {
|
|||
}
|
||||
|
||||
content +=
|
||||
" proxy /api http://localhost:" + conf.localPort.toString() + "\n"
|
||||
" proxy /api http://localhost:" + conf.localPort.toString() + " {\n"
|
||||
+ " proxy_header Host {host}\n"
|
||||
+ " proxy_header X-Forwarded-Host {host}\n"
|
||||
+ " proxy_header X-Forwarded-Proto {scheme}\n"
|
||||
// # TODO internal
|
||||
+ " }\n"
|
||||
+ "}";
|
||||
|
||||
contents.push(content);
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
module.exports.unbrick = function (req, res) {
|
||||
// hack for bricked app-cache
|
||||
if (/\.(appcache|manifest)\b/.test(req.url)) {
|
||||
res.setHeader('Content-Type', 'text/cache-manifest');
|
||||
res.end('CACHE MANIFEST\n\n# v0__DELETE__CACHE__MANIFEST__\n\nNETWORK:\n*');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
165
lib/worker.js
165
lib/worker.js
|
@ -7,8 +7,9 @@ module.exports.create = function (webserver, info, state) {
|
|||
|
||||
var PromiseA = state.Promise || require('bluebird');
|
||||
var path = require('path');
|
||||
var vhostsdir = path.join(__dirname, 'vhosts');
|
||||
var app = require('express')();
|
||||
//var vhostsdir = path.join(__dirname, 'vhosts');
|
||||
var express = require('express-lazy');
|
||||
var app = express();
|
||||
var apiHandler;
|
||||
var memstore;
|
||||
var sqlstores = {};
|
||||
|
@ -58,89 +59,29 @@ module.exports.create = function (webserver, info, state) {
|
|||
}
|
||||
*/
|
||||
|
||||
function scrubTheDubHelper(req, res/*, next*/) {
|
||||
// hack for bricked app-cache
|
||||
if (/\.appcache\b/.test(req.url)) {
|
||||
res.setHeader('Content-Type', 'text/cache-manifest');
|
||||
res.end('CACHE MANIFEST\n\n# v0__DELETE__CACHE__MANIFEST__\n\nNETWORK:\n*');
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO port number for non-443
|
||||
var escapeHtml = require('escape-html');
|
||||
var newLocation = 'https://' + req.hostname.replace(/^www\./, '') + req.url;
|
||||
var safeLocation = escapeHtml(newLocation);
|
||||
|
||||
var metaRedirect = ''
|
||||
+ '<html>\n'
|
||||
+ '<head>\n'
|
||||
+ ' <style>* { background-color: white; color: white; text-decoration: none; }</style>\n'
|
||||
+ ' <META http-equiv="refresh" content="0;URL=' + safeLocation + '">\n'
|
||||
+ '</head>\n'
|
||||
+ '<body style="display: none;">\n'
|
||||
+ ' <p>You requested an old resource. Please use this instead: \n'
|
||||
+ ' <a href="' + safeLocation + '">' + safeLocation + '</a></p>\n'
|
||||
+ '</body>\n'
|
||||
+ '</html>\n'
|
||||
;
|
||||
|
||||
// 301 redirects will not work for appcache
|
||||
res.end(metaRedirect);
|
||||
}
|
||||
|
||||
// TODO handle insecure to actual redirect
|
||||
// blog.coolaj86.com -> coolaj86.com/blog
|
||||
// hmm... that won't really matter with hsts
|
||||
// I guess I just needs letsencrypt
|
||||
|
||||
function scrubTheDub(req, res, next) {
|
||||
console.log('[no-www]', req.method, req.url);
|
||||
var host = req.hostname;
|
||||
|
||||
if (!host || 'string' !== typeof host) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO test if this is even necessary
|
||||
host = host.toLowerCase();
|
||||
|
||||
if (/^www\./.test(host)) {
|
||||
scrubTheDubHelper(req, res, next);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function handleApi(req, res, next) {
|
||||
if (!/^\/api/.test(req.url)) {
|
||||
if (!/^www\./.test(host)) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO move to caddy parser?
|
||||
if (/(^|\.)proxyable\./.test(req.hostname)) {
|
||||
// device-id-12345678.proxyable.myapp.mydomain.com => myapp.mydomain.com
|
||||
// proxyable.myapp.mydomain.com => myapp.mydomain.com
|
||||
// TODO myapp.mydomain.com.daplieproxyable.com => myapp.mydomain.com
|
||||
req.hostname = req.hostname.replace(/.*\.?proxyable\./, '');
|
||||
}
|
||||
|
||||
if (apiHandler) {
|
||||
if (apiHandler.then) {
|
||||
apiHandler.then(function (app) {
|
||||
app(req, res, next);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
apiHandler(req, res, next);
|
||||
return;
|
||||
}
|
||||
|
||||
apiHandler = require('./vhost-server').create(info.localPort, vhostsdir).create(webserver, app).then(function (app) {
|
||||
// X-Forwarded-For
|
||||
// X-Forwarded-Proto
|
||||
console.log('api server', req.hostname, req.secure, req.ip);
|
||||
apiHandler = app;
|
||||
app(req, res, next);
|
||||
});
|
||||
require('./no-www').scrubTheDub(req, res);
|
||||
}
|
||||
|
||||
if (info.trustProxy) {
|
||||
|
@ -148,7 +89,6 @@ module.exports.create = function (webserver, info, state) {
|
|||
//app.set('trust proxy', function (ip) { ... });
|
||||
}
|
||||
app.use('/', scrubTheDub);
|
||||
app.use('/', handleApi);
|
||||
|
||||
return PromiseA.all([
|
||||
cstore.create({
|
||||
|
@ -186,7 +126,7 @@ module.exports.create = function (webserver, info, state) {
|
|||
|
||||
return require('../lib/schemes-config').create(sqlstores.config).then(function (tables) {
|
||||
models.Config = tables;
|
||||
models.Config.Config.get().then(function (circ) {
|
||||
return models.Config.Config.get().then(function (vhostsMap) {
|
||||
|
||||
/*
|
||||
// todo getDomainInfo
|
||||
|
@ -195,7 +135,92 @@ module.exports.create = function (webserver, info, state) {
|
|||
utils.getDomainInfo(domain.id);
|
||||
});
|
||||
*/
|
||||
console.log(circ);
|
||||
|
||||
function handleApi(req, res, next) {
|
||||
console.log('[API]', req.method, req.url);
|
||||
var myApp;
|
||||
|
||||
if (!/^\/api/.test(req.url)) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO move to caddy parser?
|
||||
if (/(^|\.)proxyable\./.test(req.hostname)) {
|
||||
// device-id-12345678.proxyable.myapp.mydomain.com => myapp.mydomain.com
|
||||
// proxyable.myapp.mydomain.com => myapp.mydomain.com
|
||||
// TODO myapp.mydomain.com.daplieproxyable.com => myapp.mydomain.com
|
||||
req.hostname = req.hostname.replace(/.*\.?proxyable\./, '');
|
||||
}
|
||||
|
||||
if (apiHandler) {
|
||||
if (apiHandler.then) {
|
||||
apiHandler.then(function (app) {
|
||||
app(req, res, next);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
apiHandler(req, res, next);
|
||||
return;
|
||||
}
|
||||
|
||||
// apiHandler = require('./vhost-server').create(info.localPort, vhostsdir).create(webserver, app)
|
||||
myApp = express();
|
||||
apiHandler = require('./api-server').create(
|
||||
{ apppath: '../packages/apps/'
|
||||
, apipath: '../packages/apis/'
|
||||
, vhostsMap: vhostsMap
|
||||
, server: webserver
|
||||
, externalPort: info.externalPort
|
||||
}
|
||||
, { app: myApp
|
||||
, memstore: memstore
|
||||
, sqlstores: sqlstores
|
||||
, clientSqlFactory: clientFactory
|
||||
, systemSqlFactory: systemFactory
|
||||
//, handlePromise: require('./lib/common').promisableRequest;
|
||||
//, handleRejection: require('./lib/common').rejectableRequest;
|
||||
//, localPort: info.localPort
|
||||
}
|
||||
).api;
|
||||
|
||||
// TODO
|
||||
// X-Forwarded-For
|
||||
// X-Forwarded-Proto
|
||||
console.log('api server', req.hostname, req.secure, req.ip);
|
||||
|
||||
apiHandler(req, res, next);
|
||||
}
|
||||
|
||||
// TODO recase
|
||||
|
||||
//
|
||||
// Generic Template API
|
||||
//
|
||||
app
|
||||
.use(require('body-parser').json({
|
||||
strict: true // only objects and arrays
|
||||
, inflate: true
|
||||
// limited to due performance issues with JSON.parse and JSON.stringify
|
||||
// http://josh.zeigler.us/technology/web-development/how-big-is-too-big-for-json/
|
||||
//, limit: 128 * 1024
|
||||
, limit: 1.5 * 1024 * 1024
|
||||
, reviver: undefined
|
||||
, type: 'json'
|
||||
, verify: undefined
|
||||
}))
|
||||
// DO NOT allow urlencoded at any point, it is expressly forbidden
|
||||
//.use(require('body-parser').urlencoded({
|
||||
// extended: true
|
||||
//, inflate: true
|
||||
//, limit: 100 * 1024
|
||||
//, type: 'urlencoded'
|
||||
//, verify: undefined
|
||||
//}))
|
||||
.use(require('connect-send-error').error())
|
||||
;
|
||||
app.use('/', handleApi);
|
||||
|
||||
return app;
|
||||
});
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
var deserialize = require('../lib/schemes-config').deserialize;
|
||||
var getVhostsMap = require('../lib/schemes-config').getVhostsMap;
|
||||
var getDomainInfo = require('../lib/utils').getDomainInfo;
|
||||
|
||||
// var results = {"apis":[{"id":"oauth3-api","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"json":null}],"apps":[{"id":"oauth3-app","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"json":null},{"id":"hellabit-app","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"json":null},{"id":"ldsio-app","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"json":null},{"id":"ldsconnect-app","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"json":null}],"domains":[{"id":"oauth3.org","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"token":null,"accountId":null,"json":null},{"id":"lds.io","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"token":null,"accountId":null,"json":null},{"id":"ldsconnect.org","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"token":null,"accountId":null,"json":null},{"id":"hellabit.com","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"token":null,"accountId":null,"json":null},{"id":"hellabit.com#connect","createdAt":null,"updatedAt":null,"deletedAt":null,"revokedAt":null,"name":null,"token":null,"accountId":null,"json":null}],"apisDomains":[{"id":"oauth3-api_oauth3.org","createdAt":null,"updatedAt":null,"deletedAt":null,"apiId":"oauth3-api","domainId":"oauth3.org","json":null}],"appsDomains":[{"id":"oauth3-app_oauth3.org","createdAt":null,"updatedAt":null,"deletedAt":null,"appId":"oauth3-app","domainId":"oauth3.org","json":null},{"id":"hellabit-app_hellabit.com","createdAt":null,"updatedAt":null,"deletedAt":null,"appId":"hellabit-app","domainId":"hellabit.com","json":null},{"id":"ldsio-app_lds.io","createdAt":null,"updatedAt":null,"deletedAt":null,"appId":"ldsio-app","domainId":"lds.io","json":null},{"id":"ldsconnect-app_ldsconnect.org","createdAt":null,"updatedAt":null,"deletedAt":null,"appId":"ldsconnect-app","domainId":"ldsconnect.org","json":null}]};
|
||||
var results = {
|
||||
"apis":[
|
||||
{"id":"oauth3-api"}
|
||||
{"id":"org.oauth3"}
|
||||
]
|
||||
, "apps":[
|
||||
{"id":"oauth3-app"}
|
||||
|
@ -23,7 +27,8 @@ var results = {
|
|||
, {"id":"hellabit.com#connect#too"}
|
||||
]
|
||||
, "apisDomains":[
|
||||
{"id":"oauth3-api_oauth3.org","apiId":"oauth3-api","domainId":"oauth3.org"}
|
||||
{"id":"org.oauth3_oauth3.org","apiId":"org.oauth3","domainId":"oauth3.org"}
|
||||
, {"id":"org.oauth3_hellabit.com#connect###","apiId":"org.oauth3","domainId":"hellabit.com#connect###"}
|
||||
]
|
||||
,"appsDomains":[
|
||||
{"id":"oauth3-app_oauth3.org","appId":"oauth3-app","domainId":"oauth3.org"}
|
||||
|
@ -34,127 +39,9 @@ var results = {
|
|||
]
|
||||
};
|
||||
|
||||
var deserialize = require('../lib/schemes-config').deserialize;
|
||||
var getDomainInfo = require('../lib/utils').getDomainInfo;
|
||||
var config = deserialize(results);
|
||||
var req = { host: 'hellabit.com', url: '/connect' };
|
||||
var vhosts = [];
|
||||
var vhostsMap = {};
|
||||
|
||||
function sortApps(a, b) {
|
||||
// hlen isn't important in this current use of the sorter,
|
||||
// but is important for an alternate version
|
||||
var hlen = b.hostname.length - a.hostname.length;
|
||||
var plen = b.pathname.length - a.pathname.length;
|
||||
|
||||
// A directory could be named example.com, example.com# example.com##
|
||||
// to indicate order of preference (for API addons, for example)
|
||||
var dlen = (b.priority || b.dirname.length) - (a.priority || a.dirname.length);
|
||||
|
||||
if (!hlen) {
|
||||
if (!plen) {
|
||||
return dlen;
|
||||
}
|
||||
return plen;
|
||||
}
|
||||
return hlen;
|
||||
}
|
||||
|
||||
Object.keys(config.domains).forEach(function (domainname) {
|
||||
var domain = config.domains[domainname];
|
||||
var info = getDomainInfo(domainname);
|
||||
|
||||
domain.hostname = info.hostname;
|
||||
domain.pathname = '/' + (info.pathname || '');
|
||||
domain.dirname = info.dirname;
|
||||
|
||||
vhosts.push(domain);
|
||||
});
|
||||
|
||||
vhosts.sort(sortApps);
|
||||
|
||||
vhosts.forEach(function (domain) {
|
||||
console.log(domain.hostname, domain.pathname, domain.dirname);
|
||||
|
||||
if (!vhostsMap[domain.hostname]) {
|
||||
vhostsMap[domain.hostname] = { pathnamesMap: {}, pathnames: [] };
|
||||
}
|
||||
|
||||
if (!vhostsMap[domain.hostname].pathnamesMap[domain.pathname]) {
|
||||
vhostsMap[domain.hostname].pathnamesMap[domain.pathname] = { pathname: domain.pathname, apps: [] };
|
||||
vhostsMap[domain.hostname].pathnames.push(vhostsMap[domain.hostname].pathnamesMap[domain.pathname]);
|
||||
}
|
||||
|
||||
vhostsMap[domain.hostname].pathnamesMap[domain.pathname].apps.push(domain);
|
||||
});
|
||||
|
||||
if (!vhostsMap[req.host]) {
|
||||
console.log("there's no app for this hostname");
|
||||
return;
|
||||
}
|
||||
|
||||
//console.log("load an app", vhosts[req.host]);
|
||||
|
||||
//console.log(vhosts[req.host]);
|
||||
|
||||
|
||||
function getApp(route) {
|
||||
var PromiseA = require('bluebird');
|
||||
|
||||
return new PromiseA(function (resolve, reject) {
|
||||
console.log(route);
|
||||
// route.hostname
|
||||
});
|
||||
}
|
||||
|
||||
function api(req, res, next) {
|
||||
var apps;
|
||||
|
||||
vhostsMap[req.host].pathnames.some(function (route) {
|
||||
// /connect /
|
||||
if (req.url.match(route.pathname) && route.pathname.match(req.url)) {
|
||||
apps = route.apps;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
//console.log(apps);
|
||||
|
||||
function nextify(err) {
|
||||
var route;
|
||||
|
||||
if (err) {
|
||||
next(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// shortest to longest
|
||||
//route = apps.pop();
|
||||
// longest to shortest
|
||||
route = apps.shift();
|
||||
if (!route) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (route.route) {
|
||||
route.route(req, res, nextify);
|
||||
return;
|
||||
}
|
||||
|
||||
getApp(route).then(function (route) {
|
||||
route.route = route;
|
||||
try {
|
||||
route.route(req, res, nextify);
|
||||
} catch(e) {
|
||||
console.error('[App Load Error]');
|
||||
console.error(e.stack);
|
||||
nextify(new Error("couldn't load app"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
nextify();
|
||||
}
|
||||
|
||||
api(req);
|
||||
module.exports.create({
|
||||
apppath: '../packages/apps/'
|
||||
, apipath: '../packages/apis/'
|
||||
, vhostsMap: vhostsMap
|
||||
}).api(req);
|
||||
|
|
|
@ -12,7 +12,6 @@ function waitForInit(message) {
|
|||
|
||||
var msg = message.conf;
|
||||
process.removeListener('message', waitForInit);
|
||||
|
||||
require('./lib/local-server').create(msg.certPaths, msg.localPort, function (err, webserver) {
|
||||
if (err) {
|
||||
console.error('[ERROR] worker.js');
|
||||
|
@ -38,6 +37,9 @@ function waitForInit(message) {
|
|||
process.on('message', initWebServer);
|
||||
});
|
||||
});
|
||||
|
||||
// TODO conditional if 80 is being served by caddy
|
||||
require('./lib/insecure-server').create(msg.externalPort, msg.insecurePort);
|
||||
}
|
||||
|
||||
// We have to wait to get the configuration from the master process
|
||||
|
|
Loading…
Reference in New Issue