mirror of
https://github.com/seejohnrun/haste-server
synced 2025-07-14 17:13:45 -07:00
Added node modules
This commit is contained in:
parent
ca9d4c18f7
commit
d1e0644a4e
575 changed files with 77900 additions and 6 deletions
175
node_modules/connect/lib/middleware/staticCache.js
generated
vendored
Normal file
175
node_modules/connect/lib/middleware/staticCache.js
generated
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
|
||||
/*!
|
||||
* Connect - staticCache
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var http = require('http')
|
||||
, utils = require('../utils')
|
||||
, Cache = require('../cache')
|
||||
, url = require('url')
|
||||
, fs = require('fs');
|
||||
|
||||
/**
|
||||
* Enables a memory cache layer on top of
|
||||
* the `static()` middleware, serving popular
|
||||
* static files.
|
||||
*
|
||||
* By default a maximum of 128 objects are
|
||||
* held in cache, with a max of 256k each,
|
||||
* totalling ~32mb.
|
||||
*
|
||||
* A Least-Recently-Used (LRU) cache algo
|
||||
* is implemented through the `Cache` object,
|
||||
* simply rotating cache objects as they are
|
||||
* hit. This means that increasingly popular
|
||||
* objects maintain their positions while
|
||||
* others get shoved out of the stack and
|
||||
* garbage collected.
|
||||
*
|
||||
* Benchmarks:
|
||||
*
|
||||
* static(): 2700 rps
|
||||
* node-static: 5300 rps
|
||||
* static() + staticCache(): 7500 rps
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `maxObjects` max cache objects [128]
|
||||
* - `maxLength` max cache object length 256kb
|
||||
*
|
||||
* @param {Type} name
|
||||
* @return {Type}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function staticCache(options){
|
||||
var options = options || {}
|
||||
, cache = new Cache(options.maxObjects || 128)
|
||||
, maxlen = options.maxLength || 1024 * 256;
|
||||
|
||||
return function staticCache(req, res, next){
|
||||
var path = url.parse(req.url).pathname
|
||||
, ranges = req.headers.range
|
||||
, hit = cache.get(path)
|
||||
, hitCC
|
||||
, uaCC
|
||||
, header
|
||||
, age;
|
||||
|
||||
// cache static
|
||||
req.on('static', function(stream){
|
||||
var headers = res._headers
|
||||
, cc = utils.parseCacheControl(headers['cache-control'] || '')
|
||||
, contentLength = headers['content-length']
|
||||
, hit;
|
||||
|
||||
// ignore larger files
|
||||
if (!contentLength || contentLength > maxlen) return;
|
||||
|
||||
// dont cache items we shouldn't be
|
||||
if ( cc['no-cache']
|
||||
|| cc['no-store']
|
||||
|| cc['private']
|
||||
|| cc['must-revalidate']) return;
|
||||
|
||||
// if already in cache then validate
|
||||
if (hit = cache.get(path)){
|
||||
if (headers.etag == hit[0].etag) {
|
||||
hit[0].date = new Date;
|
||||
return;
|
||||
} else {
|
||||
cache.remove(path);
|
||||
}
|
||||
}
|
||||
|
||||
// validation notifiactions don't contain a steam
|
||||
if (null == stream) return;
|
||||
|
||||
// add the cache object
|
||||
var arr = cache.add(path);
|
||||
arr.push(headers);
|
||||
|
||||
// store the chunks
|
||||
stream.on('data', function(chunk){
|
||||
arr.push(chunk);
|
||||
});
|
||||
|
||||
// flag it as complete
|
||||
stream.on('end', function(){
|
||||
arr.complete = true;
|
||||
});
|
||||
});
|
||||
|
||||
// cache hit, doesnt support range requests
|
||||
if (hit && hit.complete && !ranges) {
|
||||
header = utils.merge({}, hit[0]);
|
||||
header.Age = age = (new Date - new Date(header.date)) / 1000 | 0;
|
||||
header.date = new Date().toUTCString();
|
||||
|
||||
// parse cache-controls
|
||||
hitCC = utils.parseCacheControl(header['cache-control'] || '');
|
||||
uaCC = utils.parseCacheControl(req.headers['cache-control'] || '');
|
||||
|
||||
// check if we must revalidate(bypass)
|
||||
if (hitCC['no-cache'] || uaCC['no-cache']) return next();
|
||||
|
||||
// check freshness of entity
|
||||
if (isStale(hitCC, age) || isStale(uaCC, age)) return next();
|
||||
|
||||
// conditional GET support
|
||||
if (utils.conditionalGET(req)) {
|
||||
if (!utils.modified(req, res, header)) {
|
||||
header['content-length'] = 0;
|
||||
res.writeHead(304, header);
|
||||
return res.end();
|
||||
}
|
||||
}
|
||||
|
||||
// HEAD support
|
||||
if ('HEAD' == req.method) {
|
||||
header['content-length'] = 0;
|
||||
res.writeHead(200, header);
|
||||
return res.end();
|
||||
}
|
||||
|
||||
// respond with cache
|
||||
res.writeHead(200, header);
|
||||
|
||||
// backpressure
|
||||
function write(i) {
|
||||
var buf = hit[i];
|
||||
if (!buf) return res.end();
|
||||
if (false === res.write(buf)) {
|
||||
res.once('drain', function(){
|
||||
write(++i);
|
||||
});
|
||||
} else {
|
||||
write(++i);
|
||||
}
|
||||
}
|
||||
|
||||
return write(1);
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if cache item is stale
|
||||
*
|
||||
* @param {Object} cc
|
||||
* @param {Number} age
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function isStale(cc, age) {
|
||||
return cc['max-age'] && cc['max-age'] <= age;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue