internet-information-services
Version:
internet-information-services
398 lines (224 loc) • 9.11 kB
JavaScript
;
var fs, sites;
exports.service = function (api) {
fs = api.fs;
sites = api.sites;
if (!fs.existsSync(api.projectDir + "/certificate"))
fs.mkdirSync(api.projectDir + "/certificate");
return function (request, response) {
var auth = {};
if (request.headers.cookie)
request.headers.cookie.split("; ").forEach(function (cookie) {
var arr = cookie.split("=");
auth[arr[0]] = arr[1];
});
switch (request.method.toLowerCase()) {
case "get":
response.writeHead(200);
if (String(api.admin) === auth.admin && request.url !== "/logout")
response.write(fs.readFileSync(__dirname + "/admin.html"));
else {
if (request.url === "/logout")
response.writeHead(302, {
"Set-Cookie": "admin=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax",
Location: "/"
});
else {
response.writeHead(200, {
"Set-Cookie": "admin=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax"
});
response.write(fs.readFileSync(__dirname + "/login.html"));
}
}
response.end();
break;
case "post":
var chunks = [];
var size = 0;
request.on("data", function (chunk) {
chunks.push(chunk);
size += chunk.length;
});
request.on("end", function () {
var obj = parsePost(
request.headers["content-type"] || "application/x-www-form-urlencoded",
Buffer.concat(chunks, size),
api.projectDir
);
if (obj.type) {
response.write(handle(obj, api));
} else {
if (obj.uid.length >= 4 && obj.pwd === String(api.admin)) {
setAuth(obj.pwd, response);
response.write(fs.readFileSync(__dirname + "/admin.html"));
} else {
response.write(fs.readFileSync(__dirname + "/login.html"));
}
}
response.end();
});
break;
}
}
};
function handle(obj, api) {
var data = {};
switch (obj.type) {
case "getSites":
data = sites;
break;
case "caList":
data = fs.readdirSync(api.projectDir + "/certificate");
break;
case "delFile":
var path = api.projectDir + "/certificate/" + obj.fileName;
if (fs.existsSync(path))
fs.unlinkSync(path);
data = {rc: 0};
break;
case "uploadCa":
obj.file.save("/certificate", obj.name + obj.file.filename.substr(obj.file.filename.lastIndexOf(".")));
data = {rc: 0};
break;
case "add":
if (!sites.hasOwnProperty(obj.name)) {
sites[obj.name] = JSON.parse(obj.site);
api.writeSites();
}
break;
case "del":
if (sites.hasOwnProperty(obj.site)) {
delete sites[obj.site];
setTimeout(function () {
rmdir(api.projectDir + "/wwwroot/" + obj.site);
}, 1);
api.updatePort();
api.writeSites();
}
break;
case "save":
if (sites.hasOwnProperty(obj.name)) {
var service = sites[obj.name].domains.service;
sites[obj.name] = JSON.parse(obj.site);
sites[obj.name].domains.service = service;
api.updatePort();
api.writeSites();
}
break;
case "stop":
if (sites.hasOwnProperty(obj.name)) {
if (obj.stop === "true")
sites[obj.name].stop = true;
else
delete sites[obj.name].stop;
api.writeSites();
}
break;
case "restart":
if (sites.hasOwnProperty(obj.name)) {
api.updatePort();
api.restart(obj.name);
}
break;
case "rename":
if (sites.hasOwnProperty(obj.old)) {
fs.renameSync(api.projectDir + "/wwwroot/" + obj.old, api.projectDir + "/wwwroot/" + obj.new);
var temp = sites[obj.old];
sites[obj.new] = temp;
delete sites[obj.old];
}
break;
}
return JSON.stringify(data);
}
function rmdir(dir) {
var children = fs.readdirSync(dir);
if (children.length)
children.forEach(function (path) {
path = dir + "/" + path;
var stat = fs.statSync(path);
if (stat.isDirectory())
rmdir(path);
else
fs.unlinkSync(path);
});
fs.rmdirSync(dir);
}
function setAuth(admin, response) {
var date = new Date();
date.setTime(date.getTime() + 2 * 24 * 3600 * 1000);
date = date.toGMTString();
response.writeHead(200, {
"Set-Cookie": "admin=" + admin + "; expires=" + date + "; path=/; samesite=lax; httponly"
});
}
function parsePost(enctype, data, staticDir) {
var arr = enctype.split(";");
var obj = {};
switch (arr[0]) {
case "text/plain":
data.toString().split("\r\n").forEach(function (value) {
if (value.length) {
obj[value.substring(0, value.indexOf("="))] = value.substring(value.indexOf("=") + 1);
}
});
break;
case "application/x-www-form-urlencoded":
obj = querystring.parse(data.toString());
break;
case "multipart/form-data":
var boundary = new Buffer("--" + arr[1].substring(arr[1].indexOf("=") + 1));
var i = data.indexOf(boundary);
while (data.indexOf(boundary, i + 1) >= 0) {
parsePostData(data.slice(i + boundary.length + 2, data.indexOf(boundary, i + 1)), obj, staticDir);
i = data.indexOf(boundary, i + 1);
}
break;
}
return obj;
}
function parsePostData(buffer, obj, staticDir) {
var key = new Buffer("\r\n\r\n");
var head = buffer.slice(0, buffer.indexOf(key)).toString();
var body = buffer.slice(buffer.indexOf(key) + 4, buffer.length - 2);
key = " name=\"";
var i = head.indexOf(key) + key.length;
var name = head.substring(i, head.indexOf("\"", i));
obj[name] = {name: name};
key = " filename=\"";
if (head.indexOf(key, i) > 0) {
i = head.indexOf(key) + key.length;
obj[name].filename = head.substring(i, head.indexOf("\"", i));
}
key = "Content-Type:";
if (head.indexOf(key, i) > 0) {
i = head.indexOf(key) + key.length;
obj[name].type = head.substring(i).trim();
}
if (obj[name].filename && obj[name].type) {
obj[name].data = body;
obj[name].save = function (path, filename, sync) {
path = String(path || "temp");
if (!fs.existsSync("{0}/{1}".format(staticDir, path)))
fs.mkdirSync("{0}/{1}".format(staticDir, path));
if (!filename) {
path = "{dir}/{name}.{suffix}"
.format({
dir: path,
name: this.name,
suffix: this.type.substring(this.type.indexOf("/") + 1)
})
} else if (filename.indexOf(".") < 0)
path = "{0}/{1}.{2}".format(path, filename, this.type.substring(this.type.indexOf("/") + 1));
else
path = "{0}/{1}".format(path, filename);
if (sync)
fs.writeFileSync("{0}/{1}".format(staticDir, path), this.data);
else
fs.writeFile("{0}/{1}".format(staticDir, path), this.data, function () {
});
return "/" + path;
};
} else
obj[name] = body.toString();
}