• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/base/host_mapping_rules.h"
6 
7 #include "base/logging.h"
8 #include "base/string_split.h"
9 #include "base/string_tokenizer.h"
10 #include "base/string_util.h"
11 #include "net/base/host_port_pair.h"
12 #include "net/base/net_util.h"
13 
14 namespace net {
15 
16 struct HostMappingRules::MapRule {
MapRulenet::HostMappingRules::MapRule17   MapRule() : replacement_port(-1) {}
18 
19   std::string hostname_pattern;
20   std::string replacement_hostname;
21   int replacement_port;
22 };
23 
24 struct HostMappingRules::ExclusionRule {
25   std::string hostname_pattern;
26 };
27 
HostMappingRules()28 HostMappingRules::HostMappingRules() {}
29 
~HostMappingRules()30 HostMappingRules::~HostMappingRules() {}
31 
RewriteHost(HostPortPair * host_port) const32 bool HostMappingRules::RewriteHost(HostPortPair* host_port) const {
33   // Check if the hostname was excluded.
34   for (ExclusionRuleList::const_iterator it = exclusion_rules_.begin();
35        it != exclusion_rules_.end(); ++it) {
36     const ExclusionRule& rule = *it;
37     if (MatchPattern(host_port->host(), rule.hostname_pattern))
38       return false;
39   }
40 
41   // Check if the hostname was remapped.
42   for (MapRuleList::const_iterator it = map_rules_.begin();
43        it != map_rules_.end(); ++it) {
44     const MapRule& rule = *it;
45 
46     // The rule's hostname_pattern will be something like:
47     //     www.foo.com
48     //     *.foo.com
49     //     www.foo.com:1234
50     //     *.foo.com:1234
51     // First, we'll check for a match just on hostname.
52     // If that fails, we'll check for a match with both hostname and port.
53     if (!MatchPattern(host_port->host(), rule.hostname_pattern)) {
54       std::string host_port_string = host_port->ToString();
55       if (!MatchPattern(host_port_string, rule.hostname_pattern))
56         continue;  // This rule doesn't apply.
57     }
58 
59     host_port->set_host(rule.replacement_hostname);
60     if (rule.replacement_port != -1)
61       host_port->set_port(rule.replacement_port);
62     return true;
63   }
64 
65   return false;
66 }
67 
AddRuleFromString(const std::string & rule_string)68 bool HostMappingRules::AddRuleFromString(const std::string& rule_string) {
69   std::string trimmed;
70   TrimWhitespaceASCII(rule_string, TRIM_ALL, &trimmed);
71   std::vector<std::string> parts;
72   base::SplitString(trimmed, ' ', &parts);
73 
74   // Test for EXCLUSION rule.
75   if (parts.size() == 2 && LowerCaseEqualsASCII(parts[0], "exclude")) {
76     ExclusionRule rule;
77     rule.hostname_pattern = StringToLowerASCII(parts[1]);
78     exclusion_rules_.push_back(rule);
79     return true;
80   }
81 
82   // Test for MAP rule.
83   if (parts.size() == 3 && LowerCaseEqualsASCII(parts[0], "map")) {
84     MapRule rule;
85     rule.hostname_pattern = StringToLowerASCII(parts[1]);
86 
87     if (!ParseHostAndPort(parts[2], &rule.replacement_hostname,
88                           &rule.replacement_port)) {
89       return false;  // Failed parsing the hostname/port.
90     }
91 
92     map_rules_.push_back(rule);
93     return true;
94   }
95 
96   return false;
97 }
98 
SetRulesFromString(const std::string & rules_string)99 void HostMappingRules::SetRulesFromString(const std::string& rules_string) {
100   exclusion_rules_.clear();
101   map_rules_.clear();
102 
103   StringTokenizer rules(rules_string, ",");
104   while (rules.GetNext()) {
105     bool ok = AddRuleFromString(rules.token());
106     LOG_IF(ERROR, !ok) << "Failed parsing rule: " << rules.token();
107   }
108 }
109 
110 }  // namespace net
111