paternalistic-twitter-proxy

Twitter proxy that refuses status updates with location metadata.
git clone https://wehaveforgeathome.hates.computer/paternalistic-twitter-proxy.git
Log | Files | Refs | LICENSE

proxy-table.js (4887B)


      1 /*
      2   node-http-proxy.js: Lookup table for proxy targets in node.js
      3 
      4   Copyright (c) 2010 Charlie Robbins 
      5 
      6   Permission is hereby granted, free of charge, to any person obtaining
      7   a copy of this software and associated documentation files (the
      8   "Software"), to deal in the Software without restriction, including
      9   without limitation the rights to use, copy, modify, merge, publish,
     10   distribute, sublicense, and/or sell copies of the Software, and to
     11   permit persons to whom the Software is furnished to do so, subject to
     12   the following conditions:
     13 
     14   The above copyright notice and this permission notice shall be
     15   included in all copies or substantial portions of the Software.
     16 
     17   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     20   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     21   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24 
     25 */
     26 
     27 var util = require('util'),
     28     events = require('events'),
     29     fs = require('fs');
     30 
     31 //
     32 // ### function ProxyTable (router, silent) 
     33 // #### @router {Object} Object containing the host based routes
     34 // #### @silent {Boolean} Value indicating whether we should suppress logs
     35 // #### @hostnameOnly {Boolean} Value indicating if we should route based on __hostname string only__
     36 // Constructor function for the ProxyTable responsible for getting
     37 // locations of proxy targets based on ServerRequest headers; specifically
     38 // the HTTP host header.
     39 //
     40 var ProxyTable = exports.ProxyTable = function (router, silent, hostnameOnly) {
     41   events.EventEmitter.call(this);
     42   
     43   this.silent = typeof silent !== 'undefined' ? silent : true;
     44   this.hostnameOnly = typeof hostnameOnly !== 'undefined' ? hostnameOnly : false;
     45   
     46   if (typeof router === 'object') {
     47     //
     48     // If we are passed an object literal setup 
     49     // the routes with RegExps from the router 
     50     //
     51     this.setRoutes(router);
     52   }
     53   else if (typeof router === 'string') {
     54     //
     55     // If we are passed a string then assume it is a 
     56     // file path, parse that file and watch it for changes
     57     //
     58     var self = this;
     59     this.routeFile = router;
     60     this.setRoutes(JSON.parse(fs.readFileSync(router)).router);
     61     
     62     fs.watchFile(this.routeFile, function () {
     63       fs.readFile(self.routeFile, function (err, data) {
     64         if (err) throw err;
     65         self.setRoutes(JSON.parse(data).router);
     66         self.emit('routes', self.hostnameOnly === false ? self.routes : self.router);
     67       });
     68     });
     69   }
     70   else {
     71     throw new Error('Cannot parse router with unknown type: ' + typeof router);
     72   }
     73 };
     74 
     75 // Inherit from events.EventEmitter
     76 util.inherits(ProxyTable, events.EventEmitter);
     77 
     78 //
     79 // ### function setRoutes (router) 
     80 // #### @router {Object} Object containing the host based routes
     81 // Sets the host-based routes to be used by this instance. 
     82 //
     83 ProxyTable.prototype.setRoutes = function (router) {
     84   if (!router) throw new Error('Cannot update ProxyTable routes without router.');
     85   
     86   this.router = router;
     87   
     88   if (this.hostnameOnly === false) {
     89     var self = this;
     90     this.routes = [];
     91 
     92     Object.keys(router).forEach(function (path) {
     93       var route = new RegExp(path, 'i');
     94 
     95       self.routes.push({
     96         route: route,
     97         target: router[path]
     98       });
     99     });
    100   }
    101 };
    102 
    103 //
    104 // ### function getProxyLocation (req) 
    105 // #### @req {ServerRequest} The incoming server request to get proxy information about.
    106 // Returns the proxy location based on the HTTP Headers in the  ServerRequest `req`
    107 // available to this instance.
    108 //
    109 ProxyTable.prototype.getProxyLocation = function (req) {
    110   if (!req || !req.headers || !req.headers.host) {
    111     return null;
    112   }
    113   
    114   var target = req.headers.host.split(':')[0];
    115   if (this.hostnameOnly == true) {
    116     if (this.router.hasOwnProperty(target)) {
    117       var location = this.router[target].split(':'),
    118           host = location[0],
    119           port = location.length === 1 ? 80 : location[1];
    120       
    121       return {
    122         port: port,
    123         host: host
    124       };
    125     }
    126   }
    127   else {
    128     target += req.url;
    129     for (var i in this.routes) {
    130       var match, route = this.routes[i];
    131       if (match = target.match(route.route)) {
    132         var location = route.target.split(':'),
    133             host = location[0],
    134             port = location.length === 1 ? 80 : location[1];
    135 
    136         return {
    137           port: port,
    138           host: host
    139         };
    140       }
    141     }
    142   }
    143   
    144   return null;
    145 };
    146 
    147 //
    148 // ### close function ()
    149 // Cleans up the event listeneners maintained
    150 // by this instance.
    151 //
    152 ProxyTable.prototype.close = function () {
    153   if (typeof this.routeFile === 'string') {
    154     fs.unwatchFile(this.routeFile);
    155   }
    156 };