def test_get_best_match(self): target_name = 'www.eff.org' names = [ set(['www.eff.org', 'irrelevant.long.name.eff.org', '*.org']), set(['eff.org', 'ww2.eff.org', 'test.www.eff.org']), set(['*.eff.org', '.www.eff.org']), set(['.eff.org', '*.org']), set(['www.eff.', 'www.eff.*', '*.www.eff.org']), set(['example.com', r'~^(www\.)?(eff.+)', '*.eff.*']), set(['*', r'~^(www\.)?(eff.+)']), set(['www.*', r'~^(www\.)?(eff.+)', '.test.eff.org']), set(['*.org', r'*.eff.org', 'www.eff.*']), set(['*.www.eff.org', 'www.*']), set(['*.org']), set([]), set(['example.com']) ] winners = [('exact', 'www.eff.org'), (None, None), ('exact', '.www.eff.org'), ('wildcard_start', '.eff.org'), ('wildcard_end', 'www.eff.*'), ('regex', r'~^(www\.)?(eff.+)'), ('wildcard_start', '*'), ('wildcard_end', 'www.*'), ('wildcard_start', '*.eff.org'), ('wildcard_end', 'www.*'), ('wildcard_start', '*.org'), (None, None), (None, None)] for i, winner in enumerate(winners): self.assertEqual(winner, parser.get_best_match(target_name, names[i]))
def _rank_matches_by_name(self, vhost_list, target_name): """Returns a ranked list of vhosts from vhost_list that match target_name. This method should always be followed by a call to _select_best_name_match. :param list vhost_list: list of vhosts to filter and rank :param str target_name: The name to match :returns: list of dicts containing the vhost, the matching name, and the numerical rank :rtype: list """ # Nginx chooses a matching server name for a request with precedence: # 1. exact name match # 2. longest wildcard name starting with * # 3. longest wildcard name ending with * # 4. first matching regex in order of appearance in the file matches = [] for vhost in vhost_list: name_type, name = parser.get_best_match(target_name, vhost.names) if name_type == 'exact': matches.append({ 'vhost': vhost, 'name': name, 'rank': NAME_RANK }) elif name_type == 'wildcard_start': matches.append({ 'vhost': vhost, 'name': name, 'rank': START_WILDCARD_RANK }) elif name_type == 'wildcard_end': matches.append({ 'vhost': vhost, 'name': name, 'rank': END_WILDCARD_RANK }) elif name_type == 'regex': matches.append({ 'vhost': vhost, 'name': name, 'rank': REGEX_RANK }) return sorted(matches, key=lambda x: x['rank'])