123 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
// TODO detect infinite redirects
 | 
						|
 | 
						|
module.exports.compile = module.exports.sortOpts = function (redirects) {
 | 
						|
  var dups = {};
 | 
						|
  var results = {
 | 
						|
    conflicts: {}
 | 
						|
  , patterns: []
 | 
						|
  , matchesMap: {}
 | 
						|
  };
 | 
						|
 | 
						|
  redirects.forEach(function (r) {
 | 
						|
    var bare;
 | 
						|
    var www;
 | 
						|
 | 
						|
    if ('.' === r.id[0]) {
 | 
						|
      // for consistency
 | 
						|
      // TODO this should happen at the database level
 | 
						|
      r.id = '*' + r.id;
 | 
						|
    }
 | 
						|
    if ('*' === r.id[0]) {
 | 
						|
      // TODO check that we are not trying to redirect a tld (.com, .co.uk, .org, etc)
 | 
						|
      // tlds should follow the global policy
 | 
						|
      if (r.id[1] && '.' !== r.id[1]) {
 | 
						|
        // this is not a good place to throw as the consequences of a bug would be
 | 
						|
        // very bad, but errors should never be silent, so we'll compromise
 | 
						|
        console.warn("[NON-FATAL ERROR]: ignoring redirect pattern '" + r.id + "'");
 | 
						|
        results.conflicts[r.id] = r;
 | 
						|
      }
 | 
						|
 | 
						|
      // nix the '*' for easier matching
 | 
						|
      r.id = r.id.slice(1);
 | 
						|
      if (!r.id) {
 | 
						|
        r.id = '*';
 | 
						|
      }
 | 
						|
      if (dups[r.id]) {
 | 
						|
        results.conflicts[r.id] = r;
 | 
						|
        console.warn("[NON-FATAL ERROR]: duplicate entry for redirect pattern '" + r.id + "'");
 | 
						|
      }
 | 
						|
      dups[r.id] = true;
 | 
						|
      results.patterns.push(r);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    bare = r.id.replace(/^www\./i, '');
 | 
						|
    www = r.id.replace(/^(www\.)?/i, 'www.');
 | 
						|
 | 
						|
    if (true === r.value) {
 | 
						|
      // implicit add www
 | 
						|
      results.matchesMap[bare] = www;
 | 
						|
      results.matchesMap[www] = www;
 | 
						|
    } else if (false === r.value) {
 | 
						|
      // implicit remove www
 | 
						|
      results.matchesMap[bare] = bare;
 | 
						|
      results.matchesMap[www] = bare;
 | 
						|
    } else if (!r.value) {
 | 
						|
      // (null, '', 0, undefined)
 | 
						|
      // explicitly no change
 | 
						|
      results.matchesMap[r.id] = r.id;
 | 
						|
    } else {
 | 
						|
      // explicit value
 | 
						|
      results.matchesMap[r.id] = r.value;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  results.patterns.sort(function (a, b) {
 | 
						|
    return b.id.length - a.id.length;
 | 
						|
  });
 | 
						|
 | 
						|
  return results;
 | 
						|
};
 | 
						|
 | 
						|
module.exports.redirectTo = function (hostname, opts) {
 | 
						|
  var redir = opts.matchesMap[hostname];
 | 
						|
 | 
						|
  if (redir) {
 | 
						|
    if (redir === hostname) {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    return redir;
 | 
						|
  }
 | 
						|
 | 
						|
  // longest to shortest
 | 
						|
  var hasWww = ('www.' === hostname.slice(0, 4));
 | 
						|
  //var noWww = (hasWww && hostname.slice(4)) || hostname;
 | 
						|
  //var yesWww = (hasWww && hostname) || ('www.' + hostname);
 | 
						|
 | 
						|
  redir = false;
 | 
						|
  opts.patterns.some(function (r) {
 | 
						|
    // r.id begins with a dot, such as '.foo.example.com'
 | 
						|
    if (r.id !== hostname.slice(hostname.length - r.id.length)) {
 | 
						|
      // except for the default, which is an *
 | 
						|
      if ('*' !== r.id) {
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (true === r.value) {
 | 
						|
      // implicit add www
 | 
						|
      redir = hasWww ? hostname : ('www.' + hostname);
 | 
						|
    } else if (false === r.value) {
 | 
						|
      // implicit remove www
 | 
						|
      redir = hasWww ? hostname.slice(4) : hostname;
 | 
						|
    } else if (!r.value) {
 | 
						|
      // (null, '', 0, undefined)
 | 
						|
      // explicitly no change
 | 
						|
      redir = false;
 | 
						|
    } else {
 | 
						|
      // explicit value
 | 
						|
      redir = r.value;
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
  });
 | 
						|
 | 
						|
  if (redir === hostname) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  return redir;
 | 
						|
};
 |