Initial commit
This commit is contained in:
		
							
								
								
									
										67
									
								
								net/AppDomain.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								net/AppDomain.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
var Dragonfly = global.Dragonfly;
 | 
			
		||||
 | 
			
		||||
var domain = require('domain');
 | 
			
		||||
var FatalError = require( '../errors/FatalError' );
 | 
			
		||||
 | 
			
		||||
// Message is hardcoded to prevent further exceptions occured
 | 
			
		||||
// This function must be bug-free
 | 
			
		||||
function server500( response, e )
 | 
			
		||||
{
 | 
			
		||||
	response.statusCode = 500;
 | 
			
		||||
	response.setHeader( 'Content-Type', 'text/plain' );
 | 
			
		||||
	response.end( e.message );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function serverHandle( server, request, response, rHandle )
 | 
			
		||||
{
 | 
			
		||||
	var d = domain.create();
 | 
			
		||||
 | 
			
		||||
	d.addListener( 'error', function( e ) {
 | 
			
		||||
		Dragonfly.Error( e.stack );
 | 
			
		||||
 | 
			
		||||
		try
 | 
			
		||||
		{
 | 
			
		||||
			var killtimer = setTimeout( function()
 | 
			
		||||
			{
 | 
			
		||||
				process.exit(1);
 | 
			
		||||
			}, 3000);
 | 
			
		||||
			killtimer.unref();
 | 
			
		||||
 | 
			
		||||
			server.close();
 | 
			
		||||
 | 
			
		||||
			GLOBAL.X_SERVER_CLUSTER.worker.disconnect();
 | 
			
		||||
 | 
			
		||||
			server500( response, e );
 | 
			
		||||
		}
 | 
			
		||||
		catch( ex )
 | 
			
		||||
		{
 | 
			
		||||
			Dragonfly.Error( ex.stack );
 | 
			
		||||
			process.exit();
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	d.add( request );
 | 
			
		||||
	d.add( response );
 | 
			
		||||
 | 
			
		||||
	d.run( function() {
 | 
			
		||||
		rHandle( request, response );
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Construncor
 | 
			
		||||
function AppDomain( handler, port, cluster )
 | 
			
		||||
{
 | 
			
		||||
	var http = require('http');
 | 
			
		||||
	var server = http.createServer(
 | 
			
		||||
		function(req, res) {
 | 
			
		||||
			serverHandle( server, req, res, handler );
 | 
			
		||||
		}
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	server.listen( port );
 | 
			
		||||
	Dragonfly.Info( "Listening on: " + port, Dragonfly.Visibility.VISIBLE );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports = AppDomain;
 | 
			
		||||
							
								
								
									
										111
									
								
								net/Router.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								net/Router.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
var Dragonfly = global.Dragonfly;
 | 
			
		||||
var FatalError = require( '../errors/FatalError.js' );
 | 
			
		||||
 | 
			
		||||
var MaxRedirect = 10;
 | 
			
		||||
 | 
			
		||||
var stripURI = function( url )
 | 
			
		||||
{
 | 
			
		||||
	return url.replace( /\/+/g, '/' ).replace( /^\//, '' );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var RelayPoint = function( uri, internal )
 | 
			
		||||
{
 | 
			
		||||
	this.direct = Boolean(
 | 
			
		||||
		typeof internal !== 'undefined' ? internal : false
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	this.value = internal ? uri : stripURI( uri );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var Router = function( http )
 | 
			
		||||
{
 | 
			
		||||
	this.HTTP = http;
 | 
			
		||||
	this.routes = {};
 | 
			
		||||
	this.routable = true;
 | 
			
		||||
	this.redirect_count = 0;
 | 
			
		||||
 | 
			
		||||
	// Changed when routing
 | 
			
		||||
	this.inputs = [];
 | 
			
		||||
	this.routeObj = {};
 | 
			
		||||
	this.reroute = false;
 | 
			
		||||
 | 
			
		||||
	this.relaying = new RelayPoint( http.request.raw.url );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Router.prototype.addRoute = function( name, _route, _action, _status )
 | 
			
		||||
{
 | 
			
		||||
	this.routes[ name ] = {
 | 
			
		||||
		route: _route
 | 
			
		||||
		, action: String( _action )
 | 
			
		||||
		, status: Boolean(
 | 
			
		||||
			typeof _status !== 'undefined' ? _status : true
 | 
			
		||||
		)
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Router.prototype.route = function()
 | 
			
		||||
{
 | 
			
		||||
	if( MaxRedirect < this.redirect_count )
 | 
			
		||||
		throw new FatalError( "Max redirection reached" );
 | 
			
		||||
 | 
			
		||||
	this.redirect_count ++;
 | 
			
		||||
	this.inputs[ this.inputs.length ] = this.relaying;
 | 
			
		||||
 | 
			
		||||
	var currentRoute = this.relaying.value;
 | 
			
		||||
	var r;
 | 
			
		||||
 | 
			
		||||
	if( this.relaying.direct )
 | 
			
		||||
	{
 | 
			
		||||
		if( r = this.routes[ this.relaying.value ] )
 | 
			
		||||
		{
 | 
			
		||||
			this.routable = false;
 | 
			
		||||
			this.setRoute( r );
 | 
			
		||||
			return r.action;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		for( var i in this.routes )
 | 
			
		||||
		{
 | 
			
		||||
			r = this.routes[i];
 | 
			
		||||
			if( r.route.constructor.prototype.exec )
 | 
			
		||||
			{
 | 
			
		||||
				var match = r.route.exec( currentRoute );
 | 
			
		||||
				if( match )
 | 
			
		||||
				{
 | 
			
		||||
					// Set routable to false
 | 
			
		||||
					this.routable = false;
 | 
			
		||||
					this.setRoute( r, match );
 | 
			
		||||
					return r.action;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.routable = false;
 | 
			
		||||
	return false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Set Route
 | 
			
		||||
Router.prototype.setRoute = function( _route, _match )
 | 
			
		||||
{
 | 
			
		||||
	this.routeObj = {
 | 
			
		||||
		route: _route
 | 
			
		||||
		, match: _match
 | 
			
		||||
		, router: this.router
 | 
			
		||||
		, inputs: this.inputs
 | 
			
		||||
 | 
			
		||||
		// Re-route function
 | 
			
		||||
		, reroute: function( target, direct )
 | 
			
		||||
		{
 | 
			
		||||
			Dragonfly.Log(
 | 
			
		||||
				"Reroute: " + target
 | 
			
		||||
				+ ( direct ? ", Direct" : "" )
 | 
			
		||||
			);
 | 
			
		||||
			this.relaying = new RelayPoint( target, direct );
 | 
			
		||||
			this.routable = true;
 | 
			
		||||
			this.reroute = true;
 | 
			
		||||
		}.bind( this )
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
module.exports = Router;
 | 
			
		||||
							
								
								
									
										100
									
								
								net/WebFrame.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								net/WebFrame.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
var Dragonfly = global.Dragonfly;
 | 
			
		||||
var FatalError = require( '../errors/FatalError.js' );
 | 
			
		||||
 | 
			
		||||
var Framework = function( garden )
 | 
			
		||||
{
 | 
			
		||||
	this.HTTP = garden;
 | 
			
		||||
	this.result = 0;
 | 
			
		||||
	this.planted = false;
 | 
			
		||||
	this.requestStr = "";
 | 
			
		||||
	this.requestObj = {};
 | 
			
		||||
 | 
			
		||||
	var Router = require( "./Router" );
 | 
			
		||||
	this.router = new Router( garden );
 | 
			
		||||
	this.router.addRoute( "404", false, "p404" );
 | 
			
		||||
 | 
			
		||||
	this.handlers = {
 | 
			
		||||
		"404": function()
 | 
			
		||||
		{
 | 
			
		||||
			this.HTTP.response.statusCode = 404;
 | 
			
		||||
			this.result = "404 Not Found";
 | 
			
		||||
		}.bind( this )
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Framework.prototype.run = function()
 | 
			
		||||
{
 | 
			
		||||
	var _self = this;
 | 
			
		||||
 | 
			
		||||
	var method = "GET";
 | 
			
		||||
	if( this.HTTP.request.isPost )
 | 
			
		||||
	{
 | 
			
		||||
		this.HTTP.request.raw.addListener( "data", function( data )
 | 
			
		||||
		{
 | 
			
		||||
			_self.requestStr += data.toString();
 | 
			
		||||
		})
 | 
			
		||||
		this.HTTP.request.raw.addListener( "end", function()
 | 
			
		||||
		{
 | 
			
		||||
			_self.parseResult();
 | 
			
		||||
		});
 | 
			
		||||
		
 | 
			
		||||
		method = "POST";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Dragonfly.Info(
 | 
			
		||||
		method + ": " + encodeURI( this.HTTP.request.raw.url )
 | 
			
		||||
		+ " - " + this.HTTP.request.raw.headers["user-agent"]
 | 
			
		||||
		, Dragonfly.Visibility.VISIBLE
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	if( method == "GET" ) _self.parseResult();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Framework.prototype.addHandler = function( name, method )
 | 
			
		||||
{
 | 
			
		||||
	this.handlers[ name ] = method.bind( this );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Framework.prototype.parseResult = function()
 | 
			
		||||
{
 | 
			
		||||
	while( this.router.routable )
 | 
			
		||||
	{
 | 
			
		||||
		var method = this.router.route();
 | 
			
		||||
		if( method )
 | 
			
		||||
		{
 | 
			
		||||
			Dragonfly.Debug( "Call " + method );
 | 
			
		||||
 | 
			
		||||
			if( this.handlers[ method ] )
 | 
			
		||||
			{
 | 
			
		||||
				this.handlers[ method ]( this.router.routeObj );
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		throw new FatalError( "Relay handler \"" + method + "\" is not defined" );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.plantResult();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Framework.prototype.plantResult = function()
 | 
			
		||||
{
 | 
			
		||||
	if( !this.planted )
 | 
			
		||||
	{
 | 
			
		||||
		this.planted = true;
 | 
			
		||||
		if( this.HTTP )
 | 
			
		||||
		{
 | 
			
		||||
			if( !( this.result instanceof Buffer ) )
 | 
			
		||||
			{
 | 
			
		||||
				this.result = String( this.result );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.HTTP.response.headers["Content-Length"] = this.result.length;
 | 
			
		||||
			this.HTTP.response.write( this.result );
 | 
			
		||||
			this.HTTP.response.end();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = Framework;
 | 
			
		||||
							
								
								
									
										41
									
								
								net/http.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								net/http.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
var Dragonfly = global.Dragonfly;
 | 
			
		||||
 | 
			
		||||
var HTTP = function( req, res )
 | 
			
		||||
{
 | 
			
		||||
	var _self = this;
 | 
			
		||||
	var canExit = true;
 | 
			
		||||
 | 
			
		||||
	// Simple HTTP Model
 | 
			
		||||
	this.response = {
 | 
			
		||||
		statusCode: 200
 | 
			
		||||
		, headers: {
 | 
			
		||||
			'Content-Type': 'text/html'
 | 
			
		||||
		}
 | 
			
		||||
		, write: function( str ) { _self.response.content = str }
 | 
			
		||||
		, writeLine: function( str ) { _self.response.content += str + "\n"; }
 | 
			
		||||
		, end: function()
 | 
			
		||||
		{
 | 
			
		||||
			if( canExit )
 | 
			
		||||
			{
 | 
			
		||||
				canExit = false;
 | 
			
		||||
 | 
			
		||||
				var rc = _self.response;
 | 
			
		||||
 | 
			
		||||
				res.writeHead( rc.statusCode, rc.headers );
 | 
			
		||||
				res.end( rc.content );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		, content: ''
 | 
			
		||||
		, raw: res
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	this.request = {
 | 
			
		||||
		uri: require('url').parse( req.url )
 | 
			
		||||
		, isPost: ( req.method == 'POST' )
 | 
			
		||||
		, remoteAddr: req.connection.remoteAddress
 | 
			
		||||
		, raw: req
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports = HTTP;
 | 
			
		||||
		Reference in New Issue
	
	Block a user