Skip to content

Commit 72166dc

Browse files
committed
init upload
1 parent 3a8614b commit 72166dc

File tree

11 files changed

+732
-0
lines changed

11 files changed

+732
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,12 @@
11
# nodejs-http-server
22
在nodejs平台搭建的静态http server
3+
4+
# required
5+
Node.js v4.4.4 (高版本不支持,其它版本没做兼容性测试)
6+
7+
# run
8+
start.bat
9+
10+
#config
11+
配置信息在index.js文件头部,根据注释按需求修改.
12+

css/bootstrap.min.css

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

documents/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
empty

favicon.ico

99.7 KB
Binary file not shown.

index.js

Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
//需要注意的全局变量;
2+
3+
//网站的端口号
4+
var port = 80;
5+
6+
//根目录
7+
var basePath = "/home/w";
8+
//var basePath = "E:/GitHub/nodejs-http-server.git/trunk";
9+
10+
//html主页路径
11+
var index_file_path = basePath+ "/main.html";
12+
13+
//日志文件路径
14+
var log_file_path = basePath+ "/log.txt";
15+
16+
//索引html的head区域的文件内容,指向的文件,这是相对路径;
17+
var _INDEX_HEAD_FILE_NAME = "index_head.html";
18+
19+
//读取文件时的缓冲区大小;单位:字节;
20+
var _CACHE_SIZE = 1024*50;
21+
22+
23+
/**
24+
*参数1:时间对象
25+
*参数2:年月日分隔符,默认是-
26+
*参数3:时分秒分隔符,默认是:
27+
*/
28+
var formatDate = function (d, s1, s2) {
29+
if (s1 == null) {
30+
var s1 = "-";
31+
}
32+
if (s2 == null) {
33+
var s2 = ":";
34+
}
35+
var yyyy = d.getFullYear();
36+
var mo = d.getMonth() < 9 ? ("0" + (d.getMonth()+1)) : d.getMonth()+1;
37+
var dd = d.getDate() < 10 ? ("0" + d.getDate()) : d.getDate();
38+
var hh = d.getHours() < 10 ? ("0" + d.getHours()) : d.getHours();
39+
var mi = d.getMinutes() < 10 ? ("0" + d.getMinutes()) : d.getMinutes();
40+
var ss = d.getSeconds() < 10 ? ("0" + d.getSeconds()) : d.getSeconds();
41+
return yyyy + s1 + mo + s1 + dd + " " + hh + s2 + mi + s2 + ss;
42+
}
43+
44+
var writeLog = function(data,ip){
45+
console.log(data);
46+
var fs = require("fs");
47+
var logPath = log_file_path;
48+
var options = {encoding:"utf8",flag:"a"};
49+
if(data!=null || typeof(data)=="string"){
50+
var cia = ip==null?"":"【"+ip+"】";
51+
fs.writeFile(logPath,"【"+formatDate(new Date())+"】"+cia+data+"\n",options,function(err){
52+
console.log(err);
53+
});
54+
}
55+
}
56+
57+
var readIndexData = function(){
58+
//读取文件内容
59+
var rf=require("fs");
60+
var filepath = index_file_path;
61+
var data = rf.readFileSync(filepath,'utf-8');
62+
return data;
63+
}
64+
65+
//打开并读取文件内容
66+
var openAndGetFileContent = function (fileName,charset){
67+
var fs = require("fs");
68+
if(fileName==null || fileName.length==0){
69+
return null;
70+
}
71+
var filepath = basePath+"/"+fileName;
72+
var data = null;
73+
try{
74+
var content = fs.readFileSync(filepath,{encoding:charset});
75+
return content;
76+
//data = fs.readFileSync(filepath,'binary');
77+
}catch(e){
78+
writeLog(e);
79+
writeLog("读取文件【"+fileName+"】时发生异常");
80+
}
81+
}
82+
83+
//获取文件索引页面的html的head标签内容;
84+
var getIndexHeadHtml = function(){
85+
var content = openAndGetFileContent(_INDEX_HEAD_FILE_NAME,"utf8");
86+
if(content!=null){
87+
return content;
88+
}
89+
return "";
90+
}
91+
92+
//读取文件内容,并用response输出到浏览器终端;
93+
var openAndReadFileToResponse = function(fileName,response){
94+
var fs = require("fs");
95+
if(fileName==null || fileName.length==0){
96+
return null;
97+
}
98+
var filepath = basePath+"/"+fileName;
99+
var data = null;
100+
try{
101+
var fd = fs.openSync(filepath,"r");
102+
while(true){
103+
var buffer = new Buffer(_CACHE_SIZE,"binary");
104+
var len = fs.readSync(fd,buffer,0,buffer.length);
105+
if(len>0){
106+
response.write(len==buffer.length?buffer:buffer.slice(0,len),"binary");
107+
}else{
108+
fs.closeSync(fd);
109+
break;
110+
}
111+
}
112+
//data = fs.readFileSync(filepath,'binary');
113+
return true;
114+
}catch(e){
115+
writeLog(e);
116+
writeLog("读取文件【"+fileName+"】时发生异常");
117+
}
118+
}
119+
120+
var getFileName = function (path){
121+
if(path!=null && path.length>0){
122+
var p = path.indexOf("/");
123+
var len = path.length;
124+
var q = path.indexOf("?");
125+
if(p>=0 && (p+1)<len){
126+
var end = q>0?q:len;
127+
var realName = path.substring(p+1,end);
128+
//writeLog("解析到文件名:"+realName);
129+
return realName;
130+
}
131+
}
132+
return null;
133+
}
134+
//根据文件名获取扩展名
135+
var getFileExtentision = function(fileRealName){
136+
if(fileRealName!=null && typeof(fileRealName)=="string" && fileRealName.length>0){
137+
var i1 = fileRealName.lastIndexOf("/");
138+
if(i1>0 && (i1+1)<=fileRealName.length){
139+
fileRealName = fileRealName.substring(i1+1,fileRealName.length);
140+
}
141+
var p = fileRealName.lastIndexOf(".");
142+
var len = fileRealName.length;
143+
if(p>0 && (p+1)<len){//有点,非点开头,非点结束;
144+
var ext = fileRealName.substring(p+1,len);
145+
return ext;
146+
}
147+
}
148+
}
149+
150+
var extMap = {
151+
//可扩展的table,键是扩展名,值是Mime类型;
152+
"323":"text/h323","acx":"application/internet-property-stream","ai":"application/postscript","aif":"audio/x-aiff","aifc":"audio/x-aiff","aiff":"audio/x-aiff","asf":"video/x-ms-asf","asr":"video/x-ms-asf","asx":"video/x-ms-asf","au":"audio/basic","avi":"video/x-msvideo","axs":"application/olescript","bas":"text/plain","bcpio":"application/x-bcpio","bin":"application/octet-stream","bmp":"image/bmp","c":"text/plain","cat":"application/vnd.ms-pkiseccat","cdf":"application/x-cdf","cer":"application/x-x509-ca-cert","class":"application/octet-stream","clp":"application/x-msclip","cmx":"image/x-cmx","cod":"image/cis-cod","cpio":"application/x-cpio","crd":"application/x-mscardfile","crl":"application/pkix-crl","crt":"application/x-x509-ca-cert","csh":"application/x-csh","css":"text/css","dcr":"application/x-director","der":"application/x-x509-ca-cert","dir":"application/x-director","dll":"application/x-msdownload","dms":"application/octet-stream","doc":"application/msword","dot":"application/msword","dvi":"application/x-dvi","dxr":"application/x-director","eps":"application/postscript","etx":"text/x-setext","evy":"application/envoy","exe":"application/octet-stream","fif":"application/fractals","flr":"x-world/x-vrml","gif":"image/gif","gtar":"application/x-gtar","gz":"application/x-gzip","h":"text/plain","hdf":"application/x-hdf","hlp":"application/winhlp","hqx":"application/mac-binhex40","hta":"application/hta","htc":"text/x-component","htm":"text/html","html":"text/html","htt":"text/webviewhtml","ico":"image/x-icon","ief":"image/ief","iii":"application/x-iphone","ins":"application/x-internet-signup","isp":"application/x-internet-signup","jfif":"image/pipeg","jpe":"image/jpeg","jpeg":"image/jpeg","jpg":"image/jpeg","js":"application/x-javascript","latex":"application/x-latex","lha":"application/octet-stream","lsf":"video/x-la-asf","lsx":"video/x-la-asf","lzh":"application/octet-stream","m13":"application/x-msmediaview","m14":"application/x-msmediaview","m3u":"audio/x-mpegurl","man":"application/x-troff-man","mdb":"application/x-msaccess","me":"application/x-troff-me","mht":"message/rfc822","mhtml":"message/rfc822","mid":"audio/mid","mny":"application/x-msmoney","mov":"video/quicktime","movie":"video/x-sgi-movie","mp2":"video/mpeg","mp3":"audio/mpeg","mpa":"video/mpeg","mpe":"video/mpeg","mpeg":"video/mpeg","mpg":"video/mpeg","mpp":"application/vnd.ms-project","mpv2":"video/mpeg","ms":"application/x-troff-ms","mvb":"application/x-msmediaview","nws":"message/rfc822","oda":"application/oda","p10":"application/pkcs10","p12":"application/x-pkcs12","p7b":"application/x-pkcs7-certificates","p7c":"application/x-pkcs7-mime","p7m":"application/x-pkcs7-mime","p7r":"application/x-pkcs7-certreqresp","p7s":"application/x-pkcs7-signature","pbm":"image/x-portable-bitmap","pdf":"application/pdf","pfx":"application/x-pkcs12","pgm":"image/x-portable-graymap","pko":"application/ynd.ms-pkipko","pma":"application/x-perfmon","pmc":"application/x-perfmon","pml":"application/x-perfmon","pmr":"application/x-perfmon","pmw":"application/x-perfmon","pnm":"image/x-portable-anymap","pot":"application/vnd.ms-powerpoint","ppm":"image/x-portable-pixmap","pps":"application/vnd.ms-powerpoint","ppt":"application/vnd.ms-powerpoint","prf":"application/pics-rules","ps":"application/postscript","pub":"application/x-mspublisher","qt":"video/quicktime","ra":"audio/x-pn-realaudio","ram":"audio/x-pn-realaudio","ras":"image/x-cmu-raster","rgb":"image/x-rgb","rmi":"audio/mid","roff":"application/x-troff","rtf":"application/rtf","rtx":"text/richtext","scd":"application/x-msschedule","sct":"text/scriptlet","setpay":"application/set-payment-initiation","setreg":"application/set-registration-initiation","sh":"application/x-sh","shar":"application/x-shar","sit":"application/x-stuffit","snd":"audio/basic","spc":"application/x-pkcs7-certificates","spl":"application/futuresplash","src":"application/x-wais-source","sst":"application/vnd.ms-pkicertstore","stl":"application/vnd.ms-pkistl","stm":"text/html","svg":"image/svg+xml","sv4cpio":"application/x-sv4cpio","sv4crc":"application/x-sv4crc","swf":"application/x-shockwave-flash","t":"application/x-troff","tar":"application/x-tar","tcl":"application/x-tcl","tex":"application/x-tex","texi":"application/x-texinfo","texinfo":"application/x-texinfo","tgz":"application/x-compressed","tif":"image/tiff","tiff":"image/tiff","tr":"application/x-troff","trm":"application/x-msterminal","tsv":"text/tab-separated-values","txt":"text/plain","uls":"text/iuls","ustar":"application/x-ustar","vcf":"text/x-vcard","vrml":"x-world/x-vrml","wav":"audio/x-wav","wcm":"application/vnd.ms-works","wdb":"application/vnd.ms-works","wks":"application/vnd.ms-works","wmf":"application/x-msmetafile","wps":"application/vnd.ms-works","wri":"application/x-mswrite","wrl":"x-world/x-vrml","wrz":"x-world/x-vrml","xaf":"x-world/x-vrml","xbm":"image/x-xbitmap","xla":"application/vnd.ms-excel","xlc":"application/vnd.ms-excel","xlm":"application/vnd.ms-excel","xls":"application/vnd.ms-excel","xlt":"application/vnd.ms-excel","xlw":"application/vnd.ms-excel","xof":"x-world/x-vrml","xpm":"image/x-xpixmap","xwd":"image/x-xwindowdump","z":"application/x-compress","zip":"application/zip"
153+
};
154+
//根据扩展名获取Content-Type
155+
var getContentType = function(extentision){
156+
if(extentision!=null && typeof(extentision)=="string" && extentision.length>0){
157+
var ext = extentision;
158+
var type = eval('extMap.'+ext);
159+
return type;
160+
}
161+
}
162+
163+
var checkIsFileOrFolder = function(curName){
164+
if(curName=="dir" || curName=="ls"){
165+
return "folder";
166+
}else{
167+
var fs = require('fs');
168+
var info = null;
169+
try{
170+
info = fs.statSync(basePath+"/"+curName);
171+
}catch(e){
172+
writeLog(e);
173+
}
174+
if(info!=null){
175+
if(info.isFile()){
176+
return "file";
177+
}else{
178+
return "folder";
179+
}
180+
}
181+
}
182+
}
183+
184+
//curName可能是:"dir","ls","doc/kms.pdf"
185+
var getChildFileList = function(curName){
186+
var fs = require("fs");
187+
var list = null;
188+
try{
189+
var name = (curName==null || curName.length==0)?"":"/"+curName;
190+
list = fs.readdirSync(basePath+name);
191+
}catch(e){
192+
writeLog(e);
193+
}
194+
//console.log(list);
195+
if(list!=null){
196+
return list;
197+
}else{
198+
return [];
199+
}
200+
}
201+
202+
var formatSize = function(size){
203+
var _1M = 1024*1024;
204+
if(size>_1M){
205+
return (size/_1M).toFixed(2)+"MB";
206+
}else if(size>0){
207+
return (size/1014).toFixed(2)+"KB";
208+
}else{
209+
return "";//空文件夹
210+
}
211+
}
212+
213+
var getParentFilePath = function(fileName){
214+
if(fileName=="dir" || fileName=="ls"){
215+
return "/";
216+
}else if(fileName==null || fileName==""){
217+
return "/";
218+
}else{
219+
var p = fileName.lastIndexOf("/");
220+
if(p>0){
221+
return "/"+fileName.substring(0,p);
222+
}else{
223+
return "/dir";
224+
}
225+
}
226+
}
227+
228+
var genFileListHTML = function(parentPath,list){
229+
//console.log("parentPath=",parentPath,"list=",list);
230+
var html ="<body onload='onLoad();' >";
231+
html = html + "<table id='id_tb_content_list' class='tb_custom' cellspacing='0px' cellpadding='0px'>\n<tr type='title' ><th align='center' onclick='sortByName();' >名称</th><th align='center' onclick='sortBySize();' >大小</th><th align='center' onclick='sortByDate();' >修改日期</th></tr>\n";
232+
html = html +"<tr type='upper' ><td style='padding-left:10px;padding-right:10px;'><a class=\"css-up icon\" href=\""+encodeURI(getParentFilePath(parentPath))+"\">[上级目录]</a></td><td></td><td></td></tr>";
233+
var fs = require("fs");
234+
var folderHtmlArr = [];
235+
var filesHtmlArr = [];
236+
for (var i = 0;i<list.length;i++) {
237+
var e = list[i];
238+
var name = e;
239+
var info =null;
240+
try{
241+
var pp = (parentPath==null || parentPath.length==0)?"":"/"+parentPath;
242+
info = fs.statSync(basePath+pp+"/"+e);
243+
var size = formatSize(info.size);
244+
var dd = formatDate(info.mtime);
245+
var isFile = info.isFile();
246+
var css = isFile==true?"css-file":"css-folder";
247+
var link = "<a class=\""+css+" icon\" href=\""+encodeURI(pp+"/"+name)+"\">"+name+"</a>";
248+
var htm = "<tr type='list' onmouseover=\"{style.backgroundColor='#FFFBD1';}\" onmouseout=\"{style.backgroundColor='';}\"><td>"+link+"</td><td size='"+info.size+"' >"+size+"</td><td millions='"+info.mtime.getTime()+"'>"+dd+"</td></tr>";
249+
if(isFile){
250+
filesHtmlArr.push(htm);
251+
}else{
252+
folderHtmlArr.push(htm);
253+
}
254+
}catch(e){
255+
writeLog(e);
256+
};
257+
}
258+
html = html + folderHtmlArr.join("\n")+filesHtmlArr.join("\n") +"</table></body>";
259+
return html;
260+
}
261+
262+
//创建服务器
263+
var createServer = function (){
264+
var write404HTML = function(res){
265+
res.writeHead(404,{'Content-Type': 'text/html;charset=UTF-8'});
266+
res.write("<!DOCTYPE html><html><head><meta charset='utf-8'><title>404</title></head><body><h1>404 Not Found</h1></body></html>");
267+
}
268+
var http = require('http');
269+
http.createServer(function(req, res){
270+
currentIpAddress = getClientIp(req);
271+
var u = decodeURI(req.url);
272+
writeLog("请求地址:"+u,currentIpAddress);
273+
if(u=="/"){
274+
//载入主页
275+
res.writeHead(200, {'Content-Type': 'text/html;charset=UTF-8'});
276+
var str = "";
277+
try{
278+
str = readIndexData();
279+
}catch(e){
280+
writeLog(e);
281+
str = "服务器发生异常";
282+
}
283+
res.end(str);
284+
}else if(u=="/ls" || u=="/dir"){
285+
//输出目录
286+
var list = getChildFileList();
287+
var html = genFileListHTML("",list);
288+
res.writeHead(200, {'Content-Type': 'text/html;charset=UTF-8'});
289+
res.end("<!DOCTYPE html><html>"+getIndexHeadHtml()+html+"</html>");
290+
}else{
291+
//var url = require('url');
292+
//var util = require('util');
293+
//console.log(util.inspect(url.parse(req.url, true)));
294+
var fileName = getFileName(u);
295+
if(fileName!=null && fileName.length>0){
296+
var type = checkIsFileOrFolder(fileName);
297+
if(type=="file"){
298+
var exten = getFileExtentision(fileName);
299+
console.log("fileName="+fileName);
300+
console.log("exten="+exten);
301+
var contentType = getContentType(exten);
302+
if(contentType!=null){
303+
res.writeHead(200,{'Content-Type':contentType});
304+
}
305+
//二进制形式读取
306+
var flag = openAndReadFileToResponse(fileName,res);
307+
if(flag){
308+
res.end();
309+
return;
310+
}else{
311+
write404HTML(res);
312+
}
313+
}else if(type=="folder"){
314+
var list = getChildFileList(fileName);
315+
var html = genFileListHTML(fileName,list);
316+
res.writeHead(200, {'Content-Type': 'text/html;charset=UTF-8'});
317+
res.end("<!DOCTYPE html><html>"+getIndexHeadHtml()+html+"</html>");
318+
return;
319+
}else{
320+
write404HTML(res);
321+
}
322+
}
323+
res.end();
324+
}
325+
}).listen(port);
326+
writeLog("服务器已启动,端口号:"+port);
327+
}
328+
329+
function getClientIp(req) {
330+
var ipAddress;
331+
var forwardedIpsStr = req.headers['x-forwarded-for'];
332+
if (forwardedIpsStr) {
333+
var forwardedIps = forwardedIpsStr.split(',');
334+
ipAddress = forwardedIps[0];
335+
}
336+
if (!ipAddress) {
337+
ipAddress = req.connection.remoteAddress;
338+
}
339+
return ipAddress;
340+
};
341+
342+
process.on('uncaughtException', function(err){
343+
writeLog(err);
344+
});
345+
346+
//相当于main方法
347+
createServer();

0 commit comments

Comments
 (0)