15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2010 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_mapping_rules.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h" 105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct HostMappingRules::MapRule { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MapRule() : replacement_port(-1) {} 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string hostname_pattern; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string replacement_hostname; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int replacement_port; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct HostMappingRules::ExclusionRule { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string hostname_pattern; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostMappingRules::HostMappingRules() {} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostMappingRules::~HostMappingRules() {} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HostMappingRules::RewriteHost(HostPortPair* host_port) const { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the hostname was excluded. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExclusionRuleList::const_iterator it = exclusion_rules_.begin(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != exclusion_rules_.end(); ++it) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExclusionRule& rule = *it; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (MatchPattern(host_port->host(), rule.hostname_pattern)) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the hostname was remapped. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (MapRuleList::const_iterator it = map_rules_.begin(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != map_rules_.end(); ++it) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MapRule& rule = *it; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The rule's hostname_pattern will be something like: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // www.foo.com 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // *.foo.com 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // www.foo.com:1234 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // *.foo.com:1234 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, we'll check for a match just on hostname. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If that fails, we'll check for a match with both hostname and port. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!MatchPattern(host_port->host(), rule.hostname_pattern)) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host_port_string = host_port->ToString(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!MatchPattern(host_port_string, rule.hostname_pattern)) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // This rule doesn't apply. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_port->set_host(rule.replacement_hostname); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rule.replacement_port != -1) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_port->set_port(rule.replacement_port); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HostMappingRules::AddRuleFromString(const std::string& rule_string) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string trimmed; 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TrimWhitespaceASCII(rule_string, base::TRIM_ALL, &trimmed); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> parts; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SplitString(trimmed, ' ', &parts); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test for EXCLUSION rule. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parts.size() == 2 && LowerCaseEqualsASCII(parts[0], "exclude")) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExclusionRule rule; 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) rule.hostname_pattern = base::StringToLowerASCII(parts[1]); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exclusion_rules_.push_back(rule); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test for MAP rule. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parts.size() == 3 && LowerCaseEqualsASCII(parts[0], "map")) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MapRule rule; 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) rule.hostname_pattern = base::StringToLowerASCII(parts[1]); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseHostAndPort(parts[2], &rule.replacement_hostname, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &rule.replacement_port)) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Failed parsing the hostname/port. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map_rules_.push_back(rule); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostMappingRules::SetRulesFromString(const std::string& rules_string) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exclusion_rules_.clear(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map_rules_.clear(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer rules(rules_string, ","); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (rules.GetNext()) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ok = AddRuleFromString(rules.token()); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(ERROR, !ok) << "Failed parsing rule: " << rules.token(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 111