github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/docs/examples/example-nodejs-app/node_modules/httpdispatcher/httpdispatcher.js (about)

     1  var util = require('util');
     2  var HttpDispatcher = function() {
     3  	this.listeners = { get: [ ], post: [ ] };
     4  	this.filters = { before: [ ], after: [ ] };
     5  	this.errorListener = function(req, res) { 
     6  		res.writeHead(404);
     7  		res.end();
     8  	}
     9  	this.staticFolderPrefix = '/static';
    10  	this.staticDirname;
    11  }
    12  HttpDispatcher.prototype.on = function(method, url, cb) {
    13  	this.listeners[method].push({
    14  		cb: cb,
    15  		url: url
    16  	});
    17  }
    18  HttpDispatcher.prototype.filter = function(method, url, cb) {
    19  	this.filters[method].push({
    20  		cb: cb,
    21  		url: url
    22  	});
    23  }
    24  HttpDispatcher.prototype.onGet = function(url, cb) {
    25  	this.on('get', url, cb);
    26  }	
    27  HttpDispatcher.prototype.onPost = function(url, cb) {
    28  	this.on('post', url, cb);
    29  }
    30  HttpDispatcher.prototype.onError = function(cb) {
    31  	this.errorListener = cb;
    32  }
    33  HttpDispatcher.prototype.setStatic = function(folder) {
    34  	this.on('get', new RegExp("\/"+folder), this.staticListener.bind(this));
    35  }
    36  HttpDispatcher.prototype.setStaticDirname = function(dirname) {
    37  	this.staticDirname = dirname;
    38  }
    39  HttpDispatcher.prototype.beforeFilter = function(url, cb) {
    40  	this.filter('before', url, cb);
    41  }
    42  HttpDispatcher.prototype.afterFilter = function(url, cb) {
    43  	this.filter('after', url, cb);
    44  }
    45  HttpDispatcher.prototype.dispatch = function(req, res) {
    46  	var url = require('url').parse(req.url, true);
    47  	var method = req.method.toLowerCase();
    48  	var dispatcher = this;
    49  	var doDispatch = function() {
    50  		var httpChain = new HttpChain();
    51  		var beforeFilters = this.getFilters(url.pathname, 'before');
    52  		httpChain.addAll(beforeFilters);
    53  		var listener = this.getListener(url.pathname, method);
    54  		var listenerCb = listener ? listener : this.errorListener;
    55  		httpChain.add(httpChain.getWrapped(listenerCb));
    56  		var afterFilters = this.getFilters(url.pathname, 'after');
    57  		httpChain.addAll(afterFilters);
    58  		httpChain.next(req, res);
    59  	}
    60  	if(method == 'post') {
    61  		var body = '';
    62  		req.on('data', function(data) {
    63  			body += data;
    64  		});
    65  		req.on('end', function() {
    66  			var post = require('querystring').parse(body);
    67  			req.body = body;
    68  			req.params = post;
    69  			doDispatch.call(dispatcher);
    70  		});
    71  	} else {
    72  		var url_parts = require('url').parse(req.url, true);
    73  		req.params = url_parts.query;
    74  		doDispatch.call(dispatcher);
    75  	}
    76  }
    77  HttpDispatcher.prototype.staticListener =  function(req, res) {
    78  	var url = require('url').parse(req.url, true);
    79  	var filename = "." + require('path').join(this.staticDirname, url.pathname);
    80  	var errorListener = this.errorListener;
    81  	require('fs').readFile(filename, function(err, file) {
    82  		if(err) {
    83  			errorListener(req, res);
    84  			return;
    85  		}
    86  		res.writeHeader(200, {
    87  			"Content-Type": require('mime').lookup(filename)
    88  		});
    89  		res.write(file, 'binary');
    90  		res.end();
    91  	});
    92  }
    93  HttpDispatcher.prototype.getListener = function(url, method) {
    94  	for(var i = 0, listener; i<this.listeners[method].length; i++) {
    95  		listener = this.listeners[method][i];
    96  		if(this.urlMatches(listener.url, url)) return listener.cb;
    97  	}
    98  }
    99  HttpDispatcher.prototype.getFilters = function(url, type) {
   100  	var filters = [];
   101  	for(var i = 0, filter; i<this.filters[type].length; i++) {
   102  		filter = this.filters[type][i];
   103  		if(this.urlMatches(filter.url, url)) filters.push(filter.cb);
   104  	}
   105  	return filters;
   106  }
   107  HttpDispatcher.prototype.urlMatches = function(config, url) {
   108  	if(config instanceof RegExp) return config.test(url);
   109  	if(util.inspect(config) == "[Function]") return config(url);
   110  	return config == url;
   111  }
   112  var HttpChain = function() {
   113  	this.queue = [];
   114  }
   115  HttpChain.prototype.add = function(cb) {
   116  	this.queue.push(cb);
   117  }
   118  HttpChain.prototype.addAll = function(cbs) {
   119  	for(var i = 0; i<cbs.length; i++) this.add(cbs[i]);
   120  }
   121  HttpChain.prototype.next = function(req, res) {
   122  	var cb = this.queue.shift();
   123  	if(cb) cb(req, res, this);
   124  }
   125  HttpChain.prototype.stop = function(req, res) {
   126  	res.end();
   127  }
   128  HttpChain.prototype.getWrapped = function(cb) {
   129  	return function(req, res, chain) {
   130  		cb(req, res);
   131  		chain.next(req, res);
   132  	}
   133  }
   134  module.exports = new HttpDispatcher();