BotanSS/net/Router.js

144 lines
2.8 KiB
JavaScript
Raw Normal View History

2016-02-12 21:03:21 +00:00
"use strict";
2015-04-18 14:14:36 +00:00
var cl = global.botanLoader;
2014-10-10 08:38:06 +00:00
var Dragonfly = global.Dragonfly;
2014-10-22 10:48:34 +00:00
2015-04-18 14:14:36 +00:00
var FatalError = cl.load( "botanss.errors.FatalError" )
2014-10-10 08:38:06 +00:00
var MaxRedirect = 10;
var stripURI = function( url )
{
return url.replace( /\/+/g, '/' ).replace( /^\//, '' );
};
2016-02-12 21:03:21 +00:00
class RelayPoint
2014-10-10 08:38:06 +00:00
{
2016-02-12 21:03:21 +00:00
constructor( uri, internal )
{
this.direct = Boolean(
typeof internal !== 'undefined' ? internal : false
);
2014-10-10 08:38:06 +00:00
this.route = null;
2016-02-12 21:03:21 +00:00
this.value = internal ? uri : stripURI( uri );
this.params = Array.prototype.slice.call( arguments, 2 );
}
2014-10-10 08:38:06 +00:00
};
2016-02-12 21:03:21 +00:00
var EventEmitter = require( "events" ).EventEmitter;
class Router extends EventEmitter
2014-10-10 08:38:06 +00:00
{
2016-02-12 21:03:21 +00:00
constructor ( http )
{
super();
2014-10-22 10:48:34 +00:00
2016-02-12 21:03:21 +00:00
this.HTTP = http;
this.routes = {};
this.routable = true;
this.redirect_count = 0;
2014-10-10 08:38:06 +00:00
2016-02-12 21:03:21 +00:00
// Changed when routing
this.inputs = [];
this.routeObj = {};
this.reRoute = false;
2014-10-10 08:38:06 +00:00
2016-02-12 21:03:21 +00:00
this.relaying = new RelayPoint( http.request.raw.url.split( "?" )[0] );
}
2014-10-22 10:48:34 +00:00
2016-02-12 21:03:21 +00:00
addRoute( _name, _route, _action, _status )
{
this.routes[ _name ] = {
name: _name
, route: _route
, action: String( _action )
, status: Boolean(
typeof _status !== 'undefined' ? _status : true
)
};
}
2014-10-10 08:38:06 +00:00
2016-02-12 21:03:21 +00:00
route()
{
if( MaxRedirect < this.redirect_count )
throw new FatalError( "Max redirection reached" );
2014-10-10 08:38:06 +00:00
2016-02-12 21:03:21 +00:00
this.redirect_count ++;
this.inputs[ this.inputs.length ] = this.relaying;
2014-10-10 08:38:06 +00:00
2016-02-12 21:03:21 +00:00
var currentRoute = this.relaying.value;
var r;
2014-10-10 08:38:06 +00:00
2016-02-12 21:03:21 +00:00
// Direct means reroute using route key to match the route
if( this.relaying.direct )
2014-10-10 08:38:06 +00:00
{
2016-02-12 21:03:21 +00:00
if( r = this.routes[ this.relaying.value ] )
{
this.routable = false;
this.setRoute( r );
return r.action;
}
2014-10-10 08:38:06 +00:00
}
2016-02-12 21:03:21 +00:00
else
2014-10-10 08:38:06 +00:00
{
2016-02-12 21:03:21 +00:00
// Parse RegEx rules one by one
for( var i in this.routes )
2014-10-10 08:38:06 +00:00
{
2016-02-12 21:03:21 +00:00
r = this.routes[i];
if( r.route.constructor.prototype.exec )
2014-10-10 08:38:06 +00:00
{
2016-02-12 21:03:21 +00:00
var match = r.route.exec( currentRoute );
if( match )
{
// Set routable to false
this.routable = false;
this.setRoute( r, match );
return r.action;
}
2014-10-10 08:38:06 +00:00
}
}
}
2016-02-12 21:03:21 +00:00
this.setRoute( "*", currentRoute );
this.routable = false;
return false;
2014-10-10 08:38:06 +00:00
}
2016-02-12 21:03:21 +00:00
// Set Route
setRoute( _route, _match )
{
var _self = this;
this.relaying.route = _route;
2016-02-12 21:03:21 +00:00
this.routeObj = {
route: _route
, match: _match
, router: _self.router
, inputs: _self.inputs
// Re-route function
, reRoute: function( target, direct )
{
Dragonfly.Debug(
"Reroute: " + target
+ ( direct ? ", Direct" : "" )
);
_self.relaying = new RelayPoint( target, direct );
_self.routable = true;
_self.reRoute = true;
_self.emit( "Route" );
}
2016-07-26 02:46:18 +00:00
, redirect: function( target, perm )
2016-02-12 21:03:21 +00:00
{
Dragonfly.Debug( "Redirect: " + target );
2016-07-26 02:46:18 +00:00
_self.relaying = new RelayPoint( perm ? "301" : "302", true, target );
2016-02-12 21:03:21 +00:00
_self.routable = true;
_self.reRoute = true;
_self.emit( "Route" );
}
};
}
}
2014-10-10 08:38:06 +00:00
module.exports = Router;