UNPKG

internet-information-services

Version:

internet-information-services

527 lines (306 loc) 12.1 kB
"use strict"; var gateway, sites, ports = {}, projectDir, ca = "certificate", root = "wwwroot", sitesJson = "sites.json"; exports.init = function (opt) { opt = opt || {}; projectDir = opt.path || __dirname; api.projectDir = projectDir; if (typeof opt.gateway === "function") gateway = opt.gateway; var dt = String(Date.now()); api.admin = opt.admin || dt.substr(dt.length - 6); console.log("您的后台密码是:" + api.admin); if (!fs.existsSync(root)) fs.mkdirSync(root); if (!fs.existsSync(ca)) fs.mkdirSync(ca); if (fs.existsSync(sitesJson)) loadSites(opt); if (opt.sites) { sites = opt.sites; api.sites = opt.sites; checkSites(); writeSites(); for (var site in sites) createSite(site); writeSites(); } }; function createSite(site) { if (sites.hasOwnProperty(site)) { var path, server, module; path = "{0}/{1}".format(root, site); if (site === "admin") { module = __dirname + "/admin.js"; clearRequireCache(module); sites[site].domains.service = require(module).service(api); } else { if (!fs.existsSync(path)) fs.mkdirSync(path); path += "/index.js"; if (!fs.existsSync(path)) fs.appendFileSync(path, '\nvar project = {\n\tlog: {\n\t\tadd: function(scope) {},\n\t\tlist: function(scope) {}\n\t}\n};' + '\n\nvar shared = ["head", "foot"];' + '\n\nexports.service = function (initFn) {\n\n\treturn initFn({\n\t\tproject: project,\n\t\tshared: shared,\n\t\tgateway: null\n\t});\n};'); module = projectDir + "/{0}/{1}/index.js".format(root, site); clearRequireCache(module); clearRequireCache(efPath); var ef = require(efPath); ef.setPath(projectDir + "/{0}/{1}".format(root, site)); sites[site].domains.service = require(module).service(ef.init); } sites[site].domains.forEach(function (host) { if (!ports.hasOwnProperty(host.port)) { if (host.protocol === "https") { ports[host.port] = {protocol: "https"}; if (host.options.pfx) server = https.createServer({ pfx: fs.readFileSync("{0}/{1}".format(ca, host.options.pfx)), passphrase: host.options.passphrase }, createServer); else if (host.options.cert) server = https.createServer({ cert: fs.readFileSync("{0}/{1}".format(ca, host.options.cert)), key: fs.readFileSync("{0}/{1}".format(ca, host.options.key)) }, createServer); console.log("监听 https 端口:", host.port); } else { ports[host.port] = {protocol: "http"}; server = http.createServer(createServer); console.log("监听 http 端口:", host.port); } ports[host.port].server = server; server.listen(host.port); } }); } } function checkAdmin() { var opt = {}; loadSites(opt); if (opt.sites.admin && sites.admin) sites.admin.stop = opt.sites.admin.stop; } function clearRequireCache(key) { key = key.replaceAll("\\", "/"); for (var attr in require.cache) if (Object.hasOwnProperty.call(require.cache, attr) && attr.replaceAll("\\", "/") === key) { delete require.cache[attr]; return; } } function createServer(request, response) { if (gateway && gateway(request, response) === false) { response.writeHead(400, response.headers); response.end(); return; } if (typeof request.headers.host === "string") { var domain = request.headers.host.split(":"), https = !!request.client.ssl; var host = domain[0], port = domain[1] || (https ? "443" : "80"); for (var site in sites) if (sites.hasOwnProperty(site)) { for (var i = 0; i < sites[site].domains.length; i++) { domain = sites[site].domains[i]; if (port === domain.port && host === domain.domain) { if (sites[site].stop) { if (site === "admin" && request.url === "/checkAdmin") { checkAdmin(); } response.end(); } else { if (typeof sites[site].domains.service === "function") try { sites[site].domains.service(request, response); } catch (e) { console.error(e); response.end(); } else response.end(); } return; } } } } response.writeHead(404); response.write('<head><meta charset="UTF-8" /></head>404 - 未找到!'); response.end(); } function writeSites() { if (fs.existsSync(sitesJson)) fs.writeFileSync(sitesJson, JSON.stringify(sites, null, 2)); else fs.appendFileSync(sitesJson, JSON.stringify(sites, null, 2)); } function checkSites() { var list = [], host, i, site, str; if (sites.hasOwnProperty("admin")) for (i = 0; i < sites.admin.domains.length; i++) { site = sites.admin.domains[i]; site.port = String(site.port || (site.protocol === "https" ? site.port || 8889 : site.port || 8888)); str = site.domain + ":" + site.port; if (list.indexOf(str) < 0) list.push(str); else { sites.admin.domains.splice(i, 1); i--; } } for (site in sites) if (sites.hasOwnProperty(site) && site !== "admin") for (i = 0; i < sites[site].domains.length; i++) { host = sites[site].domains[i]; host.port = String(host.port || (host.protocol === "https" ? host.port || 443 : host.port || 80)); str = host.domain + ":" + host.port; if (list.indexOf(str) < 0) list.push(str); else { sites[site].domains.splice(i, 1); i--; } } } function loadSites(opt) { if (fs.existsSync(sitesJson)) { try { opt.sites = JSON.parse(fs.readFileSync(sitesJson)); } catch (e) { console.error(e); console.error(sitesJson + " 解析出错。"); } } } function updatePort() { var _ports = {}, port; for (var site in sites) if (sites.hasOwnProperty(site)) sites[site].domains.forEach(function (domain) { _ports[domain.port] = {protocol: domain.protocol, options: domain.options}; }); for (port in _ports) if (_ports.hasOwnProperty(port)) { if (ports.hasOwnProperty(port) && _ports[port].protocol !== ports[port].protocol) { ports[port].server.close(); delete ports[port]; } if (!ports.hasOwnProperty(port)) { ports[port] = {protocol: port.protocol}; if (_ports[port].protocol === "https") { if (_ports[port].options.pfx) ports[port].server = https.createServer({ pfx: fs.readFileSync("{0}/{1}".format(ca, _ports[port].options.pfx)), passphrase: _ports[port].options.passphrase }, createServer); else if (_ports[port].options.cert) ports[port].server = https.createServer({ cert: fs.readFileSync("{0}/{1}".format(ca, _ports[port].options.cert)), key: fs.readFileSync("{0}/{1}".format(ca, _ports[port].options.key)) }, createServer); console.log("监听 https 端口:", port); } else { ports[port].server = http.createServer(createServer); console.log("监听 http 端口:", port); } ports[port].server.listen(port); } } for (port in ports) if (ports.hasOwnProperty(port) && !_ports.hasOwnProperty(port)) { ports[port].server.close(); delete ports[port]; } } var fs = require("fs"); var http = require("http"); var https = require("https"); var efPath = __dirname + "/entity-frame.js"; var api = { fs: fs, writeSites: writeSites, updatePort: updatePort, restart: createSite }; function getLen(obj) { var len = 0; for (var attr in obj) if (Object.hasOwnProperty.call(obj, attr)) len++; return len; } function getType(obj) { if (obj && obj.constructor && obj.constructor.name) return obj.constructor.name; var type = Object.prototype.toString.call(obj); return type.substring(type.indexOf(" ") + 1, type.length - 1); } function matchType(obj, type0, type1, type2) { return [].indexOf.call(arguments, getType(obj)) > 0; } function recursionFormat(str, key, obj, count) { if (count < 6) count++; else return str; if (getType(obj).toLowerCase() !== "string" && getLen(obj)) { for (var attr in obj) if (!(attr.length > 1 && attr[0] === "_") && Object.hasOwnProperty.call(obj, attr) && matchType(obj[attr], "String", "Object", "Boolean", "Number", "Array")) str = recursionFormat(str, key + "." + attr, obj[attr], count); } else if (obj !== undefined) str = str.replaceAll("{" + key + "}", obj); return str; } String.prototype.format = function () { if (this.constructor.name !== "String") return; var str = this; for (var i = 0; i < arguments.length; i++) { var obj = arguments[i]; if (getType(obj).toLowerCase() === "object") { for (var attr in obj) if (Object.hasOwnProperty.call(obj, attr) && matchType(obj[attr], "String", "Object", "Boolean", "Number", "Array")) str = recursionFormat(str, attr, obj[attr], 0); } else str = str.replaceAll("{" + i + "}", obj); } return str + ""; }; String.prototype.replaceAll = function (oldStr, newStr) { var str = this; try { oldStr = String(oldStr); newStr = String(newStr); if (newStr.indexOf(oldStr) < 0) while (str.indexOf(oldStr) >= 0) str = str.replace(oldStr, newStr); } catch (e) { return this; } return str; }; Date.prototype.format = function (fmt) { var o = { "M+": this.getMonth() + 1, "d+": this.getDate(), "h+": this.getHours(), "m+": this.getMinutes(), "s+": this.getSeconds(), "q+": Math.floor((this.getMonth() + 3) / 3), "S": this.getMilliseconds() }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; };