BotanSS/system/PageCache.js

131 lines
2.9 KiB
JavaScript
Raw Normal View History

2016-10-14 16:25:57 +00:00
"use strict";
const Dragonfly = global.Dragonfly;
const cl = global.botanLoader;
2016-10-15 03:28:55 +00:00
const Cookie = cl.load( "botanss.net.components.Cookie" );
2016-12-21 10:34:55 +00:00
const STORE_RAW = 0;
const STORE_GZ = 1;
const STORE_DEFLATE = 2;
2016-10-14 16:25:57 +00:00
class PageCache
{
constructor()
{
2016-12-21 10:34:55 +00:00
this.cache = [];
this.cache[ STORE_RAW ] = {};
this.cache[ STORE_GZ ] = {};
this.cache[ STORE_DEFLATE ] = {};
2016-10-15 03:28:55 +00:00
this.excepts = {};
2016-10-14 16:25:57 +00:00
setInterval( () => {
var d = new Date().getTime();
2016-12-21 13:36:26 +00:00
for( let store of this.cache )
for( var i in store )
2016-10-14 16:25:57 +00:00
{
2016-12-21 13:36:26 +00:00
var c = store[ i ];
if( c.ttl < d ) delete store[ i ];
2016-10-14 16:25:57 +00:00
}
2016-10-15 03:28:55 +00:00
for( var i in this.excepts )
{
var c = this.excepts[ i ];
if( c.ttl < d ) delete this.excepts[ i ];
}
2016-10-14 16:25:57 +00:00
}, 30000 );
}
store( req, res, data, ttl )
{
if( !global.pagecache ) return;
var key = req.url;
var expires = new Date().getTime() + 1000 * ttl;
2016-10-25 09:52:20 +00:00
var c = {
2016-10-14 16:25:57 +00:00
data: data
, headers: {
"Content-Length": res.headers[ "Content-Length" ]
, "Content-Type": res.headers[ "Content-Type" ]
2022-04-03 12:52:44 +00:00
, "X-Cache-Expirls": new Date( expires ).toISOString()
2016-10-14 16:25:57 +00:00
}
2016-10-25 09:52:20 +00:00
, statusCode: res.statusCode
2016-10-14 16:25:57 +00:00
, ttl: expires
};
2016-10-25 09:52:20 +00:00
if( res.headers[ "Location" ] )
c.headers[ "Location" ] = res.headers[ "Location" ];
2016-12-21 10:34:55 +00:00
if( res.headers[ "Content-Encoding" ] )
c.headers[ "Content-Encoding" ] = res.headers[ "Content-Encoding" ];
2022-04-05 14:15:01 +00:00
if( res.headers[ "Content-Security-Policy" ] )
c.headers[ "Content-Security-Policy" ] = res.headers[ "Content-Security-Policy" ];
if( res.headers[ "X-Frame-Options" ] )
c.headers[ "X-Frame-Options" ] = res.headers[ "X-Frame-Options" ];
2016-12-21 10:34:55 +00:00
this.cache[ this.__encRes( res ) ][ key ] = c;
2016-10-14 16:25:57 +00:00
Dragonfly.Debug( "StoreCache: \"" + key + "\", expire " + new Date( expires ) );
}
2016-10-15 03:28:55 +00:00
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 ) );
}
2016-10-14 16:25:57 +00:00
process( req, res )
{
2016-10-15 03:28:55 +00:00
var cookie = new Cookie( req.headers.cookie );
if( cookie.get( "sid" ) in this.excepts ) return false;
2016-10-14 16:25:57 +00:00
var url = req.url;
2016-12-21 10:34:55 +00:00
var store = this.cache[ this.__encReq( req ) ];
if( url in store )
2016-10-14 16:25:57 +00:00
{
2022-04-03 12:52:44 +00:00
var c = store[ url ];
res.writeHead( c.statusCode, c.headers );
res.end( c.data );
2016-10-14 16:25:57 +00:00
Dragonfly.Info(
"[C] "
2022-04-04 05:56:36 +00:00
+ ( req.headers[ "x-forwarded-for" ] || req.socket.remoteAddress ) + " "
2022-04-03 12:52:44 +00:00
+ req.method + ": " + url
2016-10-14 16:25:57 +00:00
+ " - " + req.headers["user-agent"]
2022-04-03 12:52:44 +00:00
+ ` in ${process.hrtime.bigint() - res._hrtime}ns`
2016-10-14 16:25:57 +00:00
, Dragonfly.Visibility.VISIBLE
);
return true;
}
return false;
}
2016-12-21 10:34:55 +00:00
__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;
}
2016-10-14 16:25:57 +00:00
}
module.exports = PageCache;