| // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/base/host_mapping_rules.h" |
| |
| #include "base/logging.h" |
| #include "base/string_split.h" |
| #include "base/string_tokenizer.h" |
| #include "base/string_util.h" |
| #include "net/base/host_port_pair.h" |
| #include "net/base/net_util.h" |
| |
| namespace net { |
| |
| struct HostMappingRules::MapRule { |
| MapRule() : replacement_port(-1) {} |
| |
| std::string hostname_pattern; |
| std::string replacement_hostname; |
| int replacement_port; |
| }; |
| |
| struct HostMappingRules::ExclusionRule { |
| std::string hostname_pattern; |
| }; |
| |
| HostMappingRules::HostMappingRules() {} |
| |
| HostMappingRules::~HostMappingRules() {} |
| |
| bool HostMappingRules::RewriteHost(HostPortPair* host_port) const { |
| // Check if the hostname was excluded. |
| for (ExclusionRuleList::const_iterator it = exclusion_rules_.begin(); |
| it != exclusion_rules_.end(); ++it) { |
| const ExclusionRule& rule = *it; |
| if (MatchPattern(host_port->host(), rule.hostname_pattern)) |
| return false; |
| } |
| |
| // Check if the hostname was remapped. |
| for (MapRuleList::const_iterator it = map_rules_.begin(); |
| it != map_rules_.end(); ++it) { |
| const MapRule& rule = *it; |
| |
| // The rule's hostname_pattern will be something like: |
| // www.foo.com |
| // *.foo.com |
| // www.foo.com:1234 |
| // *.foo.com:1234 |
| // First, we'll check for a match just on hostname. |
| // If that fails, we'll check for a match with both hostname and port. |
| if (!MatchPattern(host_port->host(), rule.hostname_pattern)) { |
| std::string host_port_string = host_port->ToString(); |
| if (!MatchPattern(host_port_string, rule.hostname_pattern)) |
| continue; // This rule doesn't apply. |
| } |
| |
| host_port->set_host(rule.replacement_hostname); |
| if (rule.replacement_port != -1) |
| host_port->set_port(rule.replacement_port); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| bool HostMappingRules::AddRuleFromString(const std::string& rule_string) { |
| std::string trimmed; |
| TrimWhitespaceASCII(rule_string, TRIM_ALL, &trimmed); |
| std::vector<std::string> parts; |
| base::SplitString(trimmed, ' ', &parts); |
| |
| // Test for EXCLUSION rule. |
| if (parts.size() == 2 && LowerCaseEqualsASCII(parts[0], "exclude")) { |
| ExclusionRule rule; |
| rule.hostname_pattern = StringToLowerASCII(parts[1]); |
| exclusion_rules_.push_back(rule); |
| return true; |
| } |
| |
| // Test for MAP rule. |
| if (parts.size() == 3 && LowerCaseEqualsASCII(parts[0], "map")) { |
| MapRule rule; |
| rule.hostname_pattern = StringToLowerASCII(parts[1]); |
| |
| if (!ParseHostAndPort(parts[2], &rule.replacement_hostname, |
| &rule.replacement_port)) { |
| return false; // Failed parsing the hostname/port. |
| } |
| |
| map_rules_.push_back(rule); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| void HostMappingRules::SetRulesFromString(const std::string& rules_string) { |
| exclusion_rules_.clear(); |
| map_rules_.clear(); |
| |
| StringTokenizer rules(rules_string, ","); |
| while (rules.GetNext()) { |
| bool ok = AddRuleFromString(rules.token()); |
| LOG_IF(ERROR, !ok) << "Failed parsing rule: " << rules.token(); |
| } |
| } |
| |
| } // namespace net |