UNPKG

mo-webserver

Version:
168 lines (150 loc) 5.39 kB
/*** ** A very simple webserver. ** ** Anchor : motadou@126.com ** Blog : motadou.github.io ** ***/ var http = require('http'); var url = require('url'); var fs = require('fs'); var path = require('path'); //默认配置项 var config = { host : '127.0.0.1', port : 80, docroot : './htdocs', filter : undefined }; //主函数 function main() { var configFilePath = process.argv.length > 2?complete(process.argv[2]):"./config.json"; fs.exists(configFilePath, function (exists) { if (exists) { var uconfig = require(configFilePath); config.host = uconfig.host || config.host; config.port = uconfig.port || config.port; config.docroot = complete(uconfig.docroot || config.docroot); config.filter = uconfig.filter?require(complete(uconfig.filter)):undefined; } //开始HTTP服务器 http.createServer(processRequestRoute).listen(config.port, config.host); console.log("mo-webserver has started.\n"); console.log("listen at : [", config.host + ":" + config.port, "]"); console.log("docroot : [", config.docroot, "]"); }); } main(); //将相对路径转换成系统所用的绝对路径 function complete(sFilePath) { if (path.isAbsolute(sFilePath)) { return sFilePath; } else { return path.normalize(process.cwd() + "/" + sFilePath); } } //路由URL function processRequestRoute(request, response) { request.remoteAddress = request.socket.remoteAddress; var pathname = url.parse(request.url).pathname; if (pathname === '/') { pathname = "/index.html"; } if (config.filter && config.filter.path_url) { pathname = config.filter.path_url(pathname); } var localPath = config.docroot + pathname; var ext = path.extname(localPath); //禁止远程访问 if (config.denyAccess && config.denyAccess.length > 0) { var islocal = false; var remoteAddress = request.connection.remoteAddress; for (var j = 0; j < config.localIPs.length; j++) { if (remoteAddress === config.localIPs[j]) { islocal = true; break; } } if (!islocal) { for (var i = 0; i < config.denyAccess.length; i++) { if (localPath === config.denyAccess[i]) { response.writeHead(403, { 'Content-Type': 'text/plain' }); response.end('403:Deny access to this page'); return; } } } } //禁止访问后端js var staticRes = true; if (staticRes && localPath.indexOf(config.srcpath) >= 0) { response.writeHead(403, { 'Content-Type': 'text/plain' }); response.end('403:Deny access to this page'); return; } fs.exists(localPath, function (exists) { if (exists) { if (staticRes) { staticResHandler(request, response, localPath, ext); //静态资源 } else { try { var handler = require(localPath); if (handler.processRequest && typeof handler.processRequest === 'function') { handler.processRequest(request, response); //动态资源 } else { response.writeHead(404, { 'Content-Type': 'text/plain' }); response.end('404:Handle Not found'); } } catch (exception) { console.log('error::url:' + request.url + 'msg:' + exception); response.writeHead(500, { "Content-Type": "text/plain" }); response.end("Server Error:" + exception); } } } else { //资源不存在 response.writeHead(404, { 'Content-Type': 'text/plain' }); response.end('404:File Not found'); } }); } //处理静态资源 function staticResHandler(request, response, filepath, ext) { fs.readFile(filepath, "binary", function (error, file) { if (error) { response.writeHead(500, { "Content-Type": "text/plain" }); response.end("Server Error:" + error); } else { printAccessLog(request, 200); response.writeHead(200, { "Content-Type": getContentTypeByExt(ext) }); response.end(file, "binary"); } }); } function printAccessLog(request, status) { console.log(request.remoteAddress, "--", "\"" + request.method + " " + request.url + " HTTP/1.1\"", status); } //得到ContentType function getContentTypeByExt(ext) { ext = ext.toLowerCase(); if (ext === '.htm' || ext === '.html') return 'text/html'; else if (ext === '.js') return 'application/x-javascript'; else if (ext === '.css') return 'text/css'; else if (ext === '.jpe' || ext === '.jpeg' || ext === '.jpg') return 'image/jpeg'; else if (ext === '.png') return 'image/png'; else if (ext === '.ico') return 'image/x-icon'; else if (ext === '.zip') return 'application/zip'; else if (ext === '.doc') return 'application/msword'; else if (ext === '.json') return 'application/json'; else return 'text/plain'; }