静态文件服务器代码整理
发布于 12 年前 作者 ctrlacv 4479 次浏览 最后一次编辑是 8 年前

staticServer.js文件

var sys = require(‘sys’),
http = require(‘http’),
url = require(‘url’),
path = require(‘path’),
fs = require(‘fs’),
mime = require(’./mime’).types,
config = require(’./config’),
zlib = require(‘zlib’),
utils = require(’./utils’);

http.createServer(function (request, response) {
var uri = url.parse(request.url).pathname;
var filename = path.join(__dirname + ‘/static’, uri);

//response.writeHead(200, { "Content-Type": "text/plain" });  
//response.write(filename);  
//response.end();  

var compressHandle = function (raw, compressMatched, statusCode, reasonPhrase) {  
    var stream = raw;  
    var acceptEncoding = request.headers['accept-encoding'] || "";  
    var matched = compressMatched; // ext.match(config.Compress.match);  

    if (matched && acceptEncoding.match(/\bgzip\b/)) {  

        response.setHeader("Content-Encoding", "gzip");  
        stream = raw.pipe(zlib.createGzip());  

    } else if (matched && acceptEncoding.match(/\bdeflate\b/)) {  

        response.setHeader("Content-Encoding", "deflate");  
        stream = raw.pipe(zlib.createDeflate());  
    }  

    response.writeHead(statusCode, reasonPhrase);  
    stream.pipe(response);  
};  

path.exists(filename, function (exists) {  
    if (!exists) {  
        response.writeHead(404, { "Content-Type": "text/plain" });  
        response.write("404 Not Found\n");  
        response.end();  
        return;  
    }  

    var ext = path.extname(filename);  
    ext = ext ? ext.slice(1) : 'unknow';  
    var contentType = mime[ext] || 'text/plain';  
    response.setHeader('Content-Type', contentType);  

    fs.stat(filename, function (err, stat) {  
        var lastModified = stat.mtime.toUTCString();  
        var ifModifiedSince = "If-Modified-Since".toLowerCase();  

        response.setHeader("Last-Modified", lastModified);  
        response.setHeader("Server", "Node/V2");  

        // add cache control  
        if (ext.match(config.Expires.fileMatch)) {  
            var expires = new Date();  
            expires.setTime(expires.getTime() + config.Expires.maxAge * 1000);  
            response.setHeader("Expires", expires.toUTCString());  
            response.setHeader("Cache-Control", "max-age=" + config.Expires.maxAge);  
        }  

        if (request.headers[ifModifiedSince] && lastModified == request.headers[ifModifiedSince]) {  
            response.writeHead(304, 'Not Modified');  
            response.end();  
            return;  
        }  
        /* 
        fs.readFile(filename, "binary", function (err, file) { 
        if (err) { 
        response.writeHead(500, 'Internal server error', { 'Content-Type': 'text/plain' }); 
        response.write(err + "\n"); 
        response.end(); 
        return; 
        } 
        response.writeHead(200, 'OK'); 
        response.write(file, 'binary'); 
        response.end(); 
        });*/  

        var compressMatched = ext.match(config.Compress.match);  

        if (request.headers["range"]) {  
            var range = utils.parseRange(request.headers["range"], stat.size);  
            if (range) {  
                response.setHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + stat.size);  
                response.setHeader("Content-Length", (range.end - range.start + 1));  
                var raw = fs.createReadStream(filename, { "start": range.start, "end": range.end });  
                compressHandle(raw, compressMatched, 206, "Partial Content");  
            }  
            else {  
                response.removeHeader("Content-Length");  
                response.writeHead(416, "Request Range Not Satisfiable");  
                response.end();  
            }  
        }  
        else {  
            var raw = fs.createReadStream(filename);  
            compressHandle(raw, compressMatched, 200, "OK");  
        }  
    });  
});  

}).listen(8000);

sys.puts(‘server running at http://localhost:8000/’);

config.js文件

exports.Expires = {
fileMatch: /^(gif|png|jpg|js|css)$/ig,
maxAge: 60 * 60 * 24 * 365
};

exports.Compress = {
match: /css|js|html/ig
};

utils.js文件

exports.parseRange = function (str, size) {
if (str.indexOf(",") != -1) {
return;
}

var range = str.split("-");  
    start = parseInt(range[0], 10),  
    end = parseInt(range[1], 10);  

// Case: -100  
if (isNaN(start)) {  
    start = size - end;  
    end = size - 1;  
}  
else if (isNaN(end)) {  
    // Case: 100-  
    end = size - 1;  
}  
  
// Invalid  
if (isNaN(start) || isNaN(end) || start > end || end > size) {  
    return;  
}  

return {start: start, end: end};  

}

utils.js文件

exports.types = {
“css”: “text/css”,
“gif”: “image/gif”,
“html”: “text/html”,
“ico”: “image/x-icon”,
“jpeg”: “image/jpeg”,
“jpg”: “image/jpeg”,
“js”: “text/javascript”,
“json”: “application/json”,
“pdf”: “application/pdf”,
“png”: “image/png”,
“txt”: “text/plain”,
“xml”: “text/xml”,
“swf”: “application/x-shockwave-flash”,
“wav”: “audio/x-wav”,
“wma”: “audio/x-ms-wma”,
“wmv”: “video/x-ms-wmv”,
“svg”: “image/svg+xml”
};

所有文件放同一个目录。

1 回复

代码没有标记…

回到顶部