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.
5 #include "net/base/host_mapping_rules.h"
7 #include "base/logging.h"
8 #include "base/strings/string_split.h"
9 #include "base/strings/string_tokenizer.h"
10 #include "base/strings/string_util.h"
11 #include "net/base/host_port_pair.h"
12 #include "net/base/net_util.h"
16 struct HostMappingRules::MapRule
{
17 MapRule() : replacement_port(-1) {}
19 std::string hostname_pattern
;
20 std::string replacement_hostname
;
24 struct HostMappingRules::ExclusionRule
{
25 std::string hostname_pattern
;
28 HostMappingRules::HostMappingRules() {}
30 HostMappingRules::~HostMappingRules() {}
32 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
))
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
;
46 // The rule's hostname_pattern will be something like:
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.
59 host_port
->set_host(rule
.replacement_hostname
);
60 if (rule
.replacement_port
!= -1)
61 host_port
->set_port(static_cast<uint16_t>(rule
.replacement_port
));
68 bool HostMappingRules::AddRuleFromString(const std::string
& rule_string
) {
70 base::TrimWhitespaceASCII(rule_string
, base::TRIM_ALL
, &trimmed
);
71 std::vector
<std::string
> parts
;
72 base::SplitString(trimmed
, ' ', &parts
);
74 // Test for EXCLUSION rule.
75 if (parts
.size() == 2 && base::LowerCaseEqualsASCII(parts
[0], "exclude")) {
77 rule
.hostname_pattern
= base::StringToLowerASCII(parts
[1]);
78 exclusion_rules_
.push_back(rule
);
83 if (parts
.size() == 3 && base::LowerCaseEqualsASCII(parts
[0], "map")) {
85 rule
.hostname_pattern
= base::StringToLowerASCII(parts
[1]);
87 if (!ParseHostAndPort(parts
[2], &rule
.replacement_hostname
,
88 &rule
.replacement_port
)) {
89 return false; // Failed parsing the hostname/port.
92 map_rules_
.push_back(rule
);
99 void HostMappingRules::SetRulesFromString(const std::string
& rules_string
) {
100 exclusion_rules_
.clear();
103 base::StringTokenizer
rules(rules_string
, ",");
104 while (rules
.GetNext()) {
105 bool ok
= AddRuleFromString(rules
.token());
106 LOG_IF(ERROR
, !ok
) << "Failed parsing rule: " << rules
.token();