Created
April 21, 2015 08:04
-
-
Save hefangshi/b864c03b35f18761ed7e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var request = require('request'); | |
var http = require('http'); | |
var cacheDir = __dirname + '/fileCache'; | |
var fs = require('fs-extra'); | |
var url = require('url'); | |
var path = require('path'); | |
var mime = require('mime'); | |
mime.default_type = -1; | |
var server = http.createServer(function (req, resp) { | |
var urlparse = url.parse(req.url); | |
var modTime = req.headers['If-Modified-Since'] || req.headers['if-modified-since']; | |
if (urlparse.pathname === '/cleanCache') { | |
cleanAllCache(function () { | |
resp.writeHead(200); | |
resp.end('ok'); | |
}); | |
return; | |
} | |
if (urlparse.pathname.lastIndexOf('/') !== urlparse.pathname.length - 1) { | |
var lastPath = urlparse.pathname.split('/').pop(); | |
var a = mime.lookup(lastPath); | |
console.log(lastPath, a); | |
if (a === -1) { | |
resp.writeHead(302, { | |
'Location': urlparse.pathname + '/' | |
}); | |
resp.end(); | |
return; | |
} | |
} | |
checkMod(urlparse.pathname, modTime, function (hasMod) { | |
if (!hasMod) { | |
resp.writeHead(304); | |
resp.end(); | |
return; | |
} | |
getCache(urlparse.pathname, function (err, stream) { | |
if (err) { | |
var content = []; | |
var x = request({ | |
url: 'http://fex-team.github.io' + urlparse.pathname, | |
method: req.method, | |
qs: urlparse.query | |
}, function (error, response, body) { | |
if (error) { | |
resp.statusCode = 500; | |
resp.end('remote fetch failed'); | |
return; | |
} | |
//console.log(urlparse.pathname, response.statusCode); | |
if (response.statusCode === 200) { | |
setCache(urlparse.pathname, Buffer.concat(content), function (err) { | |
err && console.log('set cache err', err); | |
}); | |
setCacheHeaders(urlparse.pathname, response.headers, function (err) { | |
err && console.log('set cache header err', err); | |
}); | |
} | |
}).on('error', function (error) { | |
resp.statusCode = 500; | |
resp.end('remote fetch failed'); | |
}).on('response', function (response) { | |
//console.log(urlparse.pathname, response.statusCode); | |
if (response.statusCode === 200) { | |
response.on('data', function (data) { | |
content.push(data); | |
}); | |
} | |
}); | |
delete req.headers['If-Modified-Since']; | |
delete req.headers['if-modified-since']; | |
delete req.headers.host; | |
req.pipe(x); | |
x.pipe(resp); | |
} else { | |
getCacheHeaders(urlparse.pathname, function (err, headers) { | |
if (err) { | |
cleanCache(urlparse.pathname); | |
resp.statusCode = 500; | |
resp.end('cache fetch failed'); | |
return; | |
} | |
//console.log(urlparse.pathname, 'pipe cache'); | |
headers['bae_cache'] = 1; | |
resp.writeHead(200, headers); | |
stream.pipe(resp); | |
}); | |
} | |
}); | |
}); | |
}); | |
server.listen(18080); | |
function cleanAllCache(cb) { | |
fs.remove(cacheDir, cb); | |
} | |
function cleanCache(url, cb) { | |
url = fixName(url); | |
var file = cacheDir + url; | |
fs.remove(file); | |
} | |
function checkMod(url, mod, cb) { | |
url = fixName(url); | |
var file = cacheDir + url; | |
fs.readJson(file + '.headers', function (err, headers) { | |
if (err) { | |
cb(true); | |
return; | |
} | |
var modTime = headers['Last-Modified'] || headers['last-modified']; | |
if (modTime === mod) { | |
cb(false); | |
} else { | |
cb(true); | |
} | |
}); | |
} | |
function getCache(url, cb) { | |
url = fixName(url); | |
var file = cacheDir + url; | |
fs.stat(file, function (err, stats) { | |
if (err) return cb(true); | |
if (stats.isDirectory()) { | |
console.log(file + ' is directory'); | |
cb(true); | |
} else { | |
cb(null, fs.createReadStream(file)); | |
} | |
}); | |
} | |
function setCache(url, content, cb) { | |
url = fixName(url); | |
var file = cacheDir + url; | |
fs.outputFile(file, content, cb); | |
} | |
function setCacheHeaders(url, headers, cb) { | |
url = fixName(url); | |
var file = cacheDir + url; | |
fs.outputJson(file + '.headers', headers, cb); | |
} | |
function getCacheHeaders(url, cb) { | |
url = fixName(url); | |
var file = cacheDir + url; | |
fs.readJson(file + '.headers', cb); | |
} | |
function fixName(url) { | |
if (url.lastIndexOf('/') === url.length - 1) { | |
return url + path.sep + 'index.html'; | |
} else { | |
return url; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment