Compare commits
No commits in common. "master" and "0d7f4a8deb4c287e7cbbaf8f933769bc791366cb" have entirely different histories.
master
...
0d7f4a8deb
117
Dragonfly.js
117
Dragonfly.js
@ -1,6 +1,5 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
const util = require( "util" );
|
var util = require( "util" );
|
||||||
const cluster = require( "cluster" );
|
|
||||||
|
|
||||||
/*{{{ Private methods */
|
/*{{{ Private methods */
|
||||||
// Months
|
// Months
|
||||||
@ -22,51 +21,6 @@ function logDate( date )
|
|||||||
+ ":" + padZero( date.getSeconds() )
|
+ ":" + padZero( date.getSeconds() )
|
||||||
+ " ] ";
|
+ " ] ";
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_startsWithAny( line, conds )
|
|
||||||
{
|
|
||||||
if( conds === undefined )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for( let cond of conds )
|
|
||||||
{
|
|
||||||
if( line.startsWith( cond ) )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_endsWithAny( line, conds )
|
|
||||||
{
|
|
||||||
if( conds === undefined )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for( let cond of conds )
|
|
||||||
{
|
|
||||||
if( line.endsWith( cond ) )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_containsAll( line, conds )
|
|
||||||
{
|
|
||||||
if( conds === undefined )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for( let cond of conds )
|
|
||||||
{
|
|
||||||
if( !~line.indexOf( cond ) )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
// Logger
|
// Logger
|
||||||
class Dragonfly
|
class Dragonfly
|
||||||
@ -111,7 +65,6 @@ class Dragonfly
|
|||||||
this.currentSphere = Dragonfly.defaultSphere;
|
this.currentSphere = Dragonfly.defaultSphere;
|
||||||
this.Visibility = Dragonfly.Visibility;
|
this.Visibility = Dragonfly.Visibility;
|
||||||
this.Spheres = Dragonfly.Spheres;
|
this.Spheres = Dragonfly.Spheres;
|
||||||
this._configured = false;
|
|
||||||
|
|
||||||
// Bind prototype functions
|
// Bind prototype functions
|
||||||
for( var i in Dragonfly.prototype )
|
for( var i in Dragonfly.prototype )
|
||||||
@ -119,6 +72,7 @@ class Dragonfly
|
|||||||
Dragonfly[i] = this[i].bind( this );
|
Dragonfly[i] = this[i].bind( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cluster = require( "cluster" );
|
||||||
if( cluster.isMaster )
|
if( cluster.isMaster )
|
||||||
{
|
{
|
||||||
this.logHandler = logHandler || { write: console.log };
|
this.logHandler = logHandler || { write: console.log };
|
||||||
@ -132,26 +86,14 @@ class Dragonfly
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Send to master to prevent multiple process competing to write into the handler
|
this.logHandler = { write: function( e ) { process.send({ cmd: "dragonLog", data: e }); } };
|
||||||
this.logHandler = {
|
|
||||||
write: function( e ) {
|
|
||||||
process.send(
|
|
||||||
{ cmd: "dragonLog", data: e }
|
|
||||||
, ( er ) => {
|
|
||||||
if( er )
|
|
||||||
{
|
|
||||||
console.log( er.code, e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cluster = require("cluster");
|
||||||
var tag = cluster.isMaster ? "M" : "S";
|
var tag = cluster.isMaster ? "M" : "S";
|
||||||
this.ptag = "[ " + tag + ":" + process.pid + " ] ";
|
this.ptag = "[ " + tag + ":" + process.pid + " ] ";
|
||||||
|
|
||||||
// this.Info( "Dragonfly ready.", Dragonfly.Visibility.VISIBLE );
|
this.Info( "Dragonfly ready.", Dragonfly.Visibility.VISIBLE );
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug( mesg, visibility )
|
Debug( mesg, visibility )
|
||||||
@ -166,12 +108,12 @@ class Dragonfly
|
|||||||
|
|
||||||
Warning( mesg, visibility )
|
Warning( mesg, visibility )
|
||||||
{
|
{
|
||||||
this.Log( "\x1b[33m" + mesg + "\x1b[0m", Dragonfly.Spheres.HYDRO, visibility );
|
this.Log( mesg, Dragonfly.Spheres.HYDRO, visibility );
|
||||||
}
|
}
|
||||||
|
|
||||||
Error( mesg, visibility )
|
Error( mesg, visibility )
|
||||||
{
|
{
|
||||||
this.Log( "\x1b[31m" + mesg + "\x1b[0m", Dragonfly.Spheres.LITHO, visibility );
|
this.Log( mesg, Dragonfly.Spheres.LITHO, visibility );
|
||||||
}
|
}
|
||||||
|
|
||||||
Log( mesg, sphere, visibility )
|
Log( mesg, sphere, visibility )
|
||||||
@ -198,57 +140,28 @@ class Dragonfly
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeLine()
|
writeLine ()
|
||||||
{
|
{
|
||||||
for( let x of arguments )
|
for( var i in arguments )
|
||||||
{
|
{
|
||||||
if( typeof( x ) == "string" )
|
if( typeof( arguments[i] ) == "string" )
|
||||||
{
|
{
|
||||||
if( this._exclude( x ) )
|
this.__log( arguments[i] );
|
||||||
return;
|
|
||||||
this.__log( x );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var lines = util.inspect( x );
|
var lines = util.inspect( arguments[i] ).split("\n");
|
||||||
if( this._exclude( lines ) )
|
for( var j in lines )
|
||||||
return;
|
|
||||||
|
|
||||||
for( let line of lines.split("\n") )
|
|
||||||
{
|
{
|
||||||
this.__log( line );
|
this.__log( lines[j] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_exclude( line )
|
|
||||||
{
|
|
||||||
if( !this._configured )
|
|
||||||
this._configure();
|
|
||||||
|
|
||||||
for( let ex of this._excludes )
|
|
||||||
{
|
|
||||||
if( test_startsWithAny( line, ex[ "^" ] )
|
|
||||||
&& test_endsWithAny( line, ex[ "$" ] )
|
|
||||||
&& test_containsAll( line, ex[ "~" ] ) )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_configure()
|
|
||||||
{
|
|
||||||
this._configured = true;
|
|
||||||
var cl = global.botanLoader;
|
|
||||||
this._excludes = cl.load( "config.all" ).log.exclude;
|
|
||||||
}
|
|
||||||
|
|
||||||
__log ( line )
|
__log ( line )
|
||||||
{
|
{
|
||||||
this.logHandler.write( this.ptag + logDate( new Date() ) + line + "\n" );
|
this.logHandler.write( this.ptag + logDate( new Date() ) + util.format( line ) + "\n" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
107
net/AppDomain.js
107
net/AppDomain.js
@ -1,88 +1,69 @@
|
|||||||
"use strict";
|
var cl = global.botanLoader;
|
||||||
|
var Dragonfly = global.Dragonfly;
|
||||||
|
|
||||||
const cluster = require( "cluster" );
|
var domain = require('domain');
|
||||||
const cl = global.botanLoader;
|
|
||||||
const Dragonfly = global.Dragonfly;
|
|
||||||
|
|
||||||
const domain = require('domain');
|
var FatalError = cl.load( "botanss.errors.FatalError" );
|
||||||
const http = require( "http" );
|
|
||||||
|
|
||||||
class Serving
|
// Message is hardcoded to prevent further exceptions occured
|
||||||
|
// This function must be bug-free
|
||||||
|
function server500( response, e )
|
||||||
{
|
{
|
||||||
constructor( server, handler, req, res )
|
response.statusCode = 500;
|
||||||
{
|
response.setHeader( 'Content-Type', 'text/plain' );
|
||||||
this.server = server;
|
response.end( e.message || e );
|
||||||
this.handler = handler;
|
}
|
||||||
this.req = req;
|
|
||||||
this.res = res;
|
|
||||||
|
|
||||||
var _self = this;
|
function serverHandle( server, request, response, rHandle )
|
||||||
|
{
|
||||||
|
var d = domain.create();
|
||||||
|
|
||||||
var _rejection = ( e, p ) => _self.tryExitGracefully( e );
|
d.addListener( 'error', function( e ) {
|
||||||
var _uncaught = e => _self.tryExitGracefully( e );
|
Dragonfly.Error( e.stack );
|
||||||
|
|
||||||
process
|
|
||||||
.once( "unhandledRejection", _rejection )
|
|
||||||
.once( "uncaughtException", _uncaught )
|
|
||||||
;
|
|
||||||
|
|
||||||
res._rejection = _rejection;
|
|
||||||
res._uncaught = _uncaught;
|
|
||||||
|
|
||||||
var d = domain.create();
|
|
||||||
d.addListener( 'error', ( e ) => _self.tryExitGracefully( e ) );
|
|
||||||
d.add( req );
|
|
||||||
d.add( res );
|
|
||||||
d.run( () => _self.handler( req, res ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
tryExitGracefully( e )
|
|
||||||
{
|
|
||||||
Dragonfly.Error( e.stack || e );
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var killtimer = setTimeout( () => process.exit(1), 3000 );
|
var killtimer = setTimeout( function()
|
||||||
|
{
|
||||||
|
process.exit(1);
|
||||||
|
}, 3000);
|
||||||
killtimer.unref();
|
killtimer.unref();
|
||||||
|
|
||||||
this.server.close();
|
server.close();
|
||||||
|
|
||||||
// Message is hardcoded to prevent further exceptions occured
|
global.X_SERVER_CLUSTER.worker.destroy();
|
||||||
// This function must be bug-free
|
|
||||||
this.res.statusCode = 500;
|
server500( response, e );
|
||||||
this.res.setHeader( 'Content-Type', 'text/plain' );
|
|
||||||
this.res.end( e.message || e );
|
|
||||||
}
|
}
|
||||||
catch( ex )
|
catch( ex )
|
||||||
{
|
{
|
||||||
Dragonfly.Error( ex.stack );
|
Dragonfly.Error( ex.stack );
|
||||||
|
process.exit();
|
||||||
}
|
}
|
||||||
finally
|
});
|
||||||
{
|
|
||||||
cluster.worker.disconnect();
|
d.add( request );
|
||||||
}
|
d.add( response );
|
||||||
}
|
|
||||||
|
d.run( function() {
|
||||||
|
rHandle( request, response );
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function( handler, port )
|
|
||||||
|
// Construncor
|
||||||
|
function AppDomain( handler, port, cluster )
|
||||||
{
|
{
|
||||||
if( cluster.isMaster )
|
var http = require( "http" );
|
||||||
{
|
var server = http.createServer(
|
||||||
Dragonfly.Debug( "Not Listening on master" );
|
function(req, res) {
|
||||||
return;
|
serverHandle( server, req, res, handler );
|
||||||
}
|
|
||||||
|
|
||||||
var server = null;
|
|
||||||
|
|
||||||
server = http.createServer(
|
|
||||||
function( req, res )
|
|
||||||
{
|
|
||||||
res._hrtime = process.hrtime.bigint();
|
|
||||||
new Serving( server, handler, req, res );
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
server.listen( port );
|
server.listen( port );
|
||||||
Dragonfly.Info( "Listening on: " + port, Dragonfly.Visibility.VISIBLE );
|
Dragonfly.Info( "Listening on: " + port, Dragonfly.Visibility.VISIBLE );
|
||||||
return server;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
module.exports = AppDomain;
|
||||||
|
88
net/Http.js
88
net/Http.js
@ -5,68 +5,6 @@ const Dragonfly = global.Dragonfly;
|
|||||||
|
|
||||||
const Cookie = cl.load( "botanss.net.components.Cookie" );
|
const Cookie = cl.load( "botanss.net.components.Cookie" );
|
||||||
|
|
||||||
class ContentSecurityPolicy
|
|
||||||
{
|
|
||||||
constructor()
|
|
||||||
{
|
|
||||||
this.sources = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
any()
|
|
||||||
{
|
|
||||||
return 0 < Object.keys( this.sources ).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
add( src, scope )
|
|
||||||
{
|
|
||||||
this.sources[ src ] ||= {};
|
|
||||||
this._add( this.sources[ src ], scope, src );
|
|
||||||
}
|
|
||||||
|
|
||||||
_add( s, scope, _name )
|
|
||||||
{
|
|
||||||
if( scope.startsWith( "'nonce-" ) && "'unsafe-inline'" in s )
|
|
||||||
{
|
|
||||||
Dragonfly.Warning( `Removing 'unsafe-inline' from ${_name} for ${scope}` );
|
|
||||||
delete s[ "'unsafe-inline'" ];
|
|
||||||
}
|
|
||||||
s[ scope ] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
merge( cspStr )
|
|
||||||
{
|
|
||||||
for( let src of cspStr.split( ";" ) )
|
|
||||||
{
|
|
||||||
src = src.trim();
|
|
||||||
if( !src )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var d = src.indexOf( " " );
|
|
||||||
|
|
||||||
var name = src.substr( 0, d );
|
|
||||||
|
|
||||||
this.sources[ name ] ||= {};
|
|
||||||
|
|
||||||
for( let val of src.substr( d + 1 ).split( " " ) )
|
|
||||||
{
|
|
||||||
this.sources[ name ][ val ] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toString()
|
|
||||||
{
|
|
||||||
var s = "";
|
|
||||||
for( let name in this.sources )
|
|
||||||
{
|
|
||||||
if( s )
|
|
||||||
s += " ";
|
|
||||||
s += `${name} ${Object.keys( this.sources[ name ] ).join( " " )};`;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CResponse
|
class CResponse
|
||||||
{
|
{
|
||||||
constructor( res, Http )
|
constructor( res, Http )
|
||||||
@ -75,29 +13,15 @@ class CResponse
|
|||||||
this.canExit = true;
|
this.canExit = true;
|
||||||
|
|
||||||
this.statusCode = 200;
|
this.statusCode = 200;
|
||||||
this.contentSecurityPolicy = new ContentSecurityPolicy();
|
|
||||||
this.headers = {
|
this.headers = {
|
||||||
"Content-Type": "text/html; charset=utf-8"
|
"Content-Type": "text/html; charset=utf-8"
|
||||||
, "Powered-By": "Botanical Framework (Node.js)"
|
, "Powered-By": "Botanical Framework (Node.js)"
|
||||||
, "Content-Security-Policy": this.contentSecurityPolicy
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.content = "";
|
this.content = "";
|
||||||
this.cookie = new Cookie( "", Http );
|
this.cookie = new Cookie( "", Http );
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeHeader( key, value )
|
|
||||||
{
|
|
||||||
switch( key )
|
|
||||||
{
|
|
||||||
case "Content-Security-Policy":
|
|
||||||
this.headers[ key ] = this.headers[ key ] + ' ' + value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error( `Merge header not implemented: ${key}` );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end()
|
end()
|
||||||
{
|
{
|
||||||
if( this.canExit )
|
if( this.canExit )
|
||||||
@ -106,16 +30,6 @@ class CResponse
|
|||||||
|
|
||||||
this.raw.writeHead( this.statusCode, this.headers );
|
this.raw.writeHead( this.statusCode, this.headers );
|
||||||
this.raw.end( this.content );
|
this.raw.end( this.content );
|
||||||
|
|
||||||
if( this.raw._rejection )
|
|
||||||
{
|
|
||||||
process.removeListener( "unhandledRejection", this.raw._rejection );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this.raw._uncaught )
|
|
||||||
{
|
|
||||||
process.removeListener( "uncaughtException", this.raw._uncaught );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +41,7 @@ class CResponse
|
|||||||
class CRequest
|
class CRequest
|
||||||
{
|
{
|
||||||
get isPost() { return this.raw.method == 'POST'; }
|
get isPost() { return this.raw.method == 'POST'; }
|
||||||
get remoteAddr() { return this.raw.socket.remoteAddress; }
|
get remoteAddr() { return this.raw.connection.remoteAddress; }
|
||||||
|
|
||||||
constructor( req, Http )
|
constructor( req, Http )
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ class HttpRequest extends EventEmitter
|
|||||||
{
|
{
|
||||||
this.Method = "POST";
|
this.Method = "POST";
|
||||||
this.Headers[ "Content-Type" ] = "application/x-www-form-urlencoded";
|
this.Headers[ "Content-Type" ] = "application/x-www-form-urlencoded";
|
||||||
this.RawPostData = Data == undefined ? Buffer.alloc( 0 ) : Buffer.from( Data );
|
this.RawPostData = Data == undefined ? new Buffer([]) : new Buffer( Data );
|
||||||
this.Headers[ "Content-Length" ] = this.RawPostData.length;
|
this.Headers[ "Content-Length" ] = this.RawPostData.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ class HttpRequest extends EventEmitter
|
|||||||
|
|
||||||
OnResponseReceived( Response )
|
OnResponseReceived( Response )
|
||||||
{
|
{
|
||||||
var ResponseData = Buffer.alloc( 0 );
|
var ResponseData = new Buffer( 0 );
|
||||||
|
|
||||||
Response.addListener( "data",
|
Response.addListener( "data",
|
||||||
Data => ResponseData = Buffer.concat([ ResponseData, Data ])
|
Data => ResponseData = Buffer.concat([ ResponseData, Data ])
|
||||||
|
@ -75,7 +75,7 @@ class PostFrame extends EventEmitter
|
|||||||
{
|
{
|
||||||
if( !( this.result instanceof Buffer ) )
|
if( !( this.result instanceof Buffer ) )
|
||||||
{
|
{
|
||||||
this.result = Buffer.from( this.result + "" );
|
this.result = new Buffer( this.result + "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.HTTP.response.headers["Content-Length"] = this.result.length;
|
this.HTTP.response.headers["Content-Length"] = this.result.length;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const zlib = require( "zlib" );
|
const zlib = require( "zlib" );
|
||||||
const os = require( "os" )
|
|
||||||
const fs = require( "fs" );
|
|
||||||
|
|
||||||
const cl = global.botanLoader;
|
const cl = global.botanLoader;
|
||||||
const Dragonfly = global.Dragonfly;
|
const Dragonfly = global.Dragonfly;
|
||||||
@ -14,11 +12,6 @@ const FatalError = cl.load( "botanss.errors.FatalError" );
|
|||||||
|
|
||||||
class WebFrame
|
class WebFrame
|
||||||
{
|
{
|
||||||
get ProcessTime()
|
|
||||||
{
|
|
||||||
return process.hrtime.bigint() - this.HTTP.response.raw._hrtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor( Http )
|
constructor( Http )
|
||||||
{
|
{
|
||||||
var _self = this;
|
var _self = this;
|
||||||
@ -92,7 +85,7 @@ class WebFrame
|
|||||||
var method = "GET";
|
var method = "GET";
|
||||||
if( this.HTTP.request.isPost )
|
if( this.HTTP.request.isPost )
|
||||||
{
|
{
|
||||||
this.requestStr = new CondStream( os.tmpdir(), 2048 * 128 );
|
this.requestStr = new CondStream( "/tmp/", 2048 );
|
||||||
|
|
||||||
this.HTTP.request.raw.addListener(
|
this.HTTP.request.raw.addListener(
|
||||||
"data" , ( x ) => _self.requestStr.write( x )
|
"data" , ( x ) => _self.requestStr.write( x )
|
||||||
@ -108,7 +101,7 @@ class WebFrame
|
|||||||
var url = this.HTTP.request.raw.url;
|
var url = this.HTTP.request.raw.url;
|
||||||
Dragonfly.Info(
|
Dragonfly.Info(
|
||||||
( this.HTTP.request.raw.headers[ "x-forwarded-for" ] || this.HTTP.request.remoteAddr ) + " "
|
( this.HTTP.request.raw.headers[ "x-forwarded-for" ] || this.HTTP.request.remoteAddr ) + " "
|
||||||
+ method + ": " + url
|
+ method + ": " + encodeURI( url )
|
||||||
+ " - " + this.HTTP.request.raw.headers["user-agent"]
|
+ " - " + this.HTTP.request.raw.headers["user-agent"]
|
||||||
, Dragonfly.Visibility.VISIBLE
|
, Dragonfly.Visibility.VISIBLE
|
||||||
);
|
);
|
||||||
@ -134,7 +127,7 @@ class WebFrame
|
|||||||
{
|
{
|
||||||
if( !( this.result instanceof Buffer ) )
|
if( !( this.result instanceof Buffer ) )
|
||||||
{
|
{
|
||||||
this.result = Buffer.from( this.result + "" );
|
this.result = new Buffer( this.result + "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
var acceptEncoding = this.HTTP.request.headers[ "accept-encoding" ] || "";
|
var acceptEncoding = this.HTTP.request.headers[ "accept-encoding" ] || "";
|
||||||
@ -175,7 +168,7 @@ class WebFrame
|
|||||||
this.HTTP.response.headers["Content-Length"] = data.length;
|
this.HTTP.response.headers["Content-Length"] = data.length;
|
||||||
this.HTTP.response.write( data );
|
this.HTTP.response.write( data );
|
||||||
this.HTTP.response.end();
|
this.HTTP.response.end();
|
||||||
Dragonfly.Debug( `Result Planted: ${this.ProcessTime}ns` );
|
Dragonfly.Debug( "Result Planted" );
|
||||||
}
|
}
|
||||||
|
|
||||||
__storeCache( data, cache, ttl )
|
__storeCache( data, cache, ttl )
|
||||||
@ -210,6 +203,8 @@ class WebFrame
|
|||||||
|
|
||||||
resp.headers[ "Content-Disposition" ] = "attachment; filename=\"" + name + "\"";
|
resp.headers[ "Content-Disposition" ] = "attachment; filename=\"" + name + "\"";
|
||||||
|
|
||||||
|
var fs = require( "fs" );
|
||||||
|
|
||||||
Dragonfly.Debug( "Stream out: " + path );
|
Dragonfly.Debug( "Stream out: " + path );
|
||||||
|
|
||||||
var rs = fs.createReadStream( path );
|
var rs = fs.createReadStream( path );
|
||||||
|
@ -11,7 +11,7 @@ class HttpRequestComplete extends EventArgs
|
|||||||
if( ResponseData === undefined )
|
if( ResponseData === undefined )
|
||||||
{
|
{
|
||||||
this.statusCode = -1;
|
this.statusCode = -1;
|
||||||
this.Data = Buffer.alloc( 0 );
|
this.Data = new Buffer( 0 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
73
package.js
73
package.js
@ -1,55 +1,34 @@
|
|||||||
"use strict";
|
|
||||||
// The Package Loader
|
// The Package Loader
|
||||||
|
|
||||||
const fs = require( "fs" );
|
var fs = require( "fs" );
|
||||||
const cluster = require( "cluster" );
|
var rootNS = {
|
||||||
|
botanss: "./"
|
||||||
|
};
|
||||||
|
|
||||||
class Package
|
var Package = function() { };
|
||||||
|
|
||||||
|
Package.prototype.rootNS = function( name, path )
|
||||||
{
|
{
|
||||||
constructor()
|
if( rootNS[ name ] ) return;
|
||||||
|
rootNS[ name ] = fs.realpathSync( path ) + "/";
|
||||||
|
};
|
||||||
|
|
||||||
|
Package.prototype.load = function( _class, deCache )
|
||||||
|
{
|
||||||
|
var fSep = _class.indexOf( "." );
|
||||||
|
var nsdomain = _class.substr( 0, fSep );
|
||||||
|
_class = _class.substr( fSep + 1 ).replace( /\./g, "/" );
|
||||||
|
|
||||||
|
var file = rootNS[ nsdomain ] + _class;
|
||||||
|
|
||||||
|
var lClass = require( file );
|
||||||
|
// TODO: Implements filewatcher
|
||||||
|
|
||||||
|
if( deCache )
|
||||||
{
|
{
|
||||||
this._rootNS = { botanss: "./" };
|
delete require.cache[ require.resolve( file ) ];
|
||||||
}
|
}
|
||||||
|
return lClass;
|
||||||
rootNS( name, path )
|
};
|
||||||
{
|
|
||||||
if( this._rootNS[ name ] ) return;
|
|
||||||
this._rootNS[ name ] = fs.realpathSync( path ) + "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
load( _class )
|
|
||||||
{
|
|
||||||
var fSep = _class.indexOf( "." );
|
|
||||||
var nsdomain = _class.substr( 0, fSep );
|
|
||||||
_class = _class.substr( fSep + 1 ).replace( /\./g, "/" );
|
|
||||||
|
|
||||||
var file = this._rootNS[ nsdomain ] + _class;
|
|
||||||
|
|
||||||
if( global.debug && cluster.worker )
|
|
||||||
{
|
|
||||||
var src = require.resolve( file );
|
|
||||||
if(!( src in require.cache ))
|
|
||||||
{
|
|
||||||
fs.watch( src, this._reload.bind({ "src": src }) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return require( file );
|
|
||||||
}
|
|
||||||
|
|
||||||
_reload( e, filename )
|
|
||||||
{
|
|
||||||
if( this._lock == cluster.worker.id )
|
|
||||||
return;
|
|
||||||
this._lock = cluster.worker.id;
|
|
||||||
|
|
||||||
setTimeout( () =>
|
|
||||||
{
|
|
||||||
global.Dragonfly.Info( `Change detected: ${this.src}, reloading` );
|
|
||||||
cluster.worker.disconnect();
|
|
||||||
setTimeout( () => process.exit(0), 3000 ).unref();
|
|
||||||
} , 200 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
global.botanLoader = new Package();
|
global.botanLoader = new Package();
|
||||||
|
@ -50,7 +50,7 @@ class PageCache
|
|||||||
, headers: {
|
, headers: {
|
||||||
"Content-Length": res.headers[ "Content-Length" ]
|
"Content-Length": res.headers[ "Content-Length" ]
|
||||||
, "Content-Type": res.headers[ "Content-Type" ]
|
, "Content-Type": res.headers[ "Content-Type" ]
|
||||||
, "X-Cache-Expirls": new Date( expires ).toISOString()
|
, "X-Cache-Expires": new Date( expires )
|
||||||
}
|
}
|
||||||
, statusCode: res.statusCode
|
, statusCode: res.statusCode
|
||||||
, ttl: expires
|
, ttl: expires
|
||||||
@ -62,12 +62,6 @@ class PageCache
|
|||||||
if( res.headers[ "Content-Encoding" ] )
|
if( res.headers[ "Content-Encoding" ] )
|
||||||
c.headers[ "Content-Encoding" ] = 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;
|
this.cache[ this.__encRes( res ) ][ key ] = c;
|
||||||
Dragonfly.Debug( "StoreCache: \"" + key + "\", expire " + new Date( expires ) );
|
Dragonfly.Debug( "StoreCache: \"" + key + "\", expire " + new Date( expires ) );
|
||||||
}
|
}
|
||||||
@ -93,19 +87,18 @@ class PageCache
|
|||||||
|
|
||||||
if( url in store )
|
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 ];
|
var c = store[ url ];
|
||||||
res.writeHead( c.statusCode, c.headers );
|
res.writeHead( c.statusCode, c.headers );
|
||||||
res.end( c.data );
|
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 true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ class ConditionalStream extends String
|
|||||||
this.__error = "Received data is too large to process";
|
this.__error = "Received data is too large to process";
|
||||||
}
|
}
|
||||||
|
|
||||||
return Buffer.from( this.hexData, "hex" ).toString( enc );
|
return new Buffer( this.hexData, "hex" ).toString( enc );
|
||||||
}
|
}
|
||||||
|
|
||||||
resultStream()
|
resultStream()
|
||||||
|
Loading…
Reference in New Issue
Block a user