internet-information-services
Version:
internet-information-services
527 lines (306 loc) • 12.1 kB
JavaScript
;
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;
};