"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-Expirls": new Date( expires ).toISOString() } , 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" ]; 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" ]; 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 ) { var c = store[ url ]; res.writeHead( c.statusCode, c.headers ); res.end( c.data ); Dragonfly.Info( "[C] " + ( req.headers[ "x-forwarded-for" ] || req.socket.remoteAddress ) + " " + req.method + ": " + url + " - " + req.headers["user-agent"] + ` in ${process.hrtime.bigint() - res._hrtime}ns` , Dragonfly.Visibility.VISIBLE ); 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;