124 lines
2.6 KiB
JavaScript
124 lines
2.6 KiB
JavaScript
"use strict";
|
|
|
|
const Dragonfly = global.Dragonfly;
|
|
const cl = global.botanLoader;
|
|
|
|
const Cookie = cl.load( "botanss.net.components.Cookie" );
|
|
|
|
const STORE_RAW = 0;
|
|
const STORE_GZ = 1;
|
|
const STORE_DEFLATE = 2;
|
|
|
|
class PageCache
|
|
{
|
|
constructor()
|
|
{
|
|
this.cache = [];
|
|
|
|
this.cache[ STORE_RAW ] = {};
|
|
this.cache[ STORE_GZ ] = {};
|
|
this.cache[ STORE_DEFLATE ] = {};
|
|
|
|
this.excepts = {};
|
|
|
|
setInterval( () => {
|
|
var d = new Date().getTime();
|
|
for( let store of this.cache )
|
|
for( var i in store )
|
|
{
|
|
var c = store[ i ];
|
|
if( c.ttl < d ) delete store[ i ];
|
|
}
|
|
|
|
for( var i in this.excepts )
|
|
{
|
|
var c = this.excepts[ i ];
|
|
if( c.ttl < d ) delete this.excepts[ i ];
|
|
}
|
|
}, 30000 );
|
|
}
|
|
|
|
store( req, res, data, ttl )
|
|
{
|
|
if( !global.pagecache ) return;
|
|
var key = req.url;
|
|
|
|
var expires = new Date().getTime() + 1000 * ttl;
|
|
|
|
var c = {
|
|
data: data
|
|
, headers: {
|
|
"Content-Length": res.headers[ "Content-Length" ]
|
|
, "Content-Type": res.headers[ "Content-Type" ]
|
|
, "X-Cache-Expires": new Date( expires )
|
|
}
|
|
, statusCode: res.statusCode
|
|
, ttl: expires
|
|
};
|
|
|
|
if( res.headers[ "Location" ] )
|
|
c.headers[ "Location" ] = res.headers[ "Location" ];
|
|
|
|
if( res.headers[ "Content-Encoding" ] )
|
|
c.headers[ "Content-Encoding" ] = res.headers[ "Content-Encoding" ];
|
|
|
|
this.cache[ this.__encRes( res ) ][ key ] = c;
|
|
Dragonfly.Debug( "StoreCache: \"" + key + "\", expire " + new Date( expires ) );
|
|
}
|
|
|
|
except( sid, ttl )
|
|
{
|
|
if( !global.pagecache ) return;
|
|
|
|
var expires = new Date().getTime() + 1000 * ttl;
|
|
|
|
this.excepts[ sid ] = { ttl: expires };
|
|
|
|
Dragonfly.Debug( "CacheExcept: \"" + sid.substr( 0, 8 ) + "\", expire " + new Date( expires ) );
|
|
}
|
|
|
|
process( req, res )
|
|
{
|
|
var cookie = new Cookie( req.headers.cookie );
|
|
if( cookie.get( "sid" ) in this.excepts ) return false;
|
|
|
|
var url = req.url;
|
|
var store = this.cache[ this.__encReq( req ) ];
|
|
|
|
if( url in store )
|
|
{
|
|
Dragonfly.Info(
|
|
"[C] "
|
|
+ ( req.headers[ "x-forwarded-for" ] || req.connection.remoteAddress ) + " "
|
|
+ req.method + ": " + encodeURI( url )
|
|
+ " - " + req.headers["user-agent"]
|
|
, Dragonfly.Visibility.VISIBLE
|
|
);
|
|
|
|
var c = store[ url ];
|
|
res.writeHead( c.statusCode, c.headers );
|
|
res.end( c.data );
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
__encRes( res )
|
|
{
|
|
return { "deflate": STORE_DEFLATE, "gzip": STORE_GZ }[ res.headers[ "Content-Encoding" ] ] || STORE_RAW;
|
|
}
|
|
|
|
__encReq( req )
|
|
{
|
|
var enc = req.headers[ "accept-encoding" ] || "";
|
|
if( ~enc.indexOf( "deflate" ) ) return STORE_DEFLATE;
|
|
else if( ~enc.indexOf( "gzip" ) ) return STORE_GZ;
|
|
return STORE_RAW;
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = PageCache;
|