summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-18 08:03:38 +0000
committereroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-18 08:03:38 +0000
commit9087aa3c473281af9c216d060d00baa4e1af4216 (patch)
tree11020a066a239d0042247611052c43f7fd0859ef
parent3517fd50b20611670f08aedfff25451f6fe9e313 (diff)
downloadchromium_src-9087aa3c473281af9c216d060d00baa4e1af4216.zip
chromium_src-9087aa3c473281af9c216d060d00baa4e1af4216.tar.gz
chromium_src-9087aa3c473281af9c216d060d00baa4e1af4216.tar.bz2
Add a command-line flag to remap hostnames based on patterns.
This is a generalization of the --testing-fixed-server flag. BUG=36053 TEST=MappedHostResolverTest.* Review URL: http://codereview.chromium.org/647001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39342 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/io_thread.cc65
-rw-r--r--chrome/common/chrome_switches.cc14
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--net/base/fixed_host_resolver.cc46
-rw-r--r--net/base/fixed_host_resolver.h41
-rw-r--r--net/base/host_resolver.h7
-rw-r--r--net/base/mapped_host_resolver.cc111
-rw-r--r--net/base/mapped_host_resolver.h79
-rw-r--r--net/base/mapped_host_resolver_unittest.cc148
-rwxr-xr-xnet/net.gyp5
10 files changed, 402 insertions, 115 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 1b62f9c..1aafdf4 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -11,7 +11,7 @@
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/net/url_fetcher.h"
#include "chrome/common/chrome_switches.h"
-#include "net/base/fixed_host_resolver.h"
+#include "net/base/mapped_host_resolver.h"
#include "net/base/host_cache.h"
#include "net/base/host_resolver.h"
#include "net/base/host_resolver_impl.h"
@@ -28,34 +28,47 @@ net::HostResolver* CreateGlobalHostResolver(
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- // The FixedHostResolver allows us to send all network requests through
- // a designated test server.
+ global_host_resolver =
+ net::CreateSystemHostResolver(network_change_notifier);
+
+ if (!command_line.HasSwitch(switches::kEnableIPv6)) {
+ // Measure impact of allowing IPv6 support without probing.
+ const FieldTrial::Probability kDivisor = 100;
+ const FieldTrial::Probability kProbability = 50; // 50% probability.
+ FieldTrial* trial = new FieldTrial("IPv6_Probe", kDivisor);
+ int skip_group = trial->AppendGroup("_IPv6_probe_skipped", kProbability);
+ trial->AppendGroup("_IPv6_probe_done",
+ FieldTrial::kAllRemainingProbability);
+ bool use_ipv6_probe = (trial->group() != skip_group);
+
+ // Perform probe, and then optionally use result to disable IPv6.
+ // Some users report confused OS handling of IPv6, leading to large
+ // latency. If we can show that IPv6 is not supported, then disabliing it
+ // will work around such problems.
+ if ((!net::IPv6Supported() && use_ipv6_probe) ||
+ command_line.HasSwitch(switches::kDisableIPv6))
+ global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
+ }
+
+ std::string hostname_remappings;
+
if (command_line.HasSwitch(switches::kFixedHost)) {
std::string host =
command_line.GetSwitchValueASCII(switches::kFixedHost);
- global_host_resolver = new net::FixedHostResolver(host);
- } else {
- global_host_resolver =
- net::CreateSystemHostResolver(network_change_notifier);
-
- if (!command_line.HasSwitch(switches::kEnableIPv6)) {
- // Measure impact of allowing IPv6 support without probing.
- const FieldTrial::Probability kDivisor = 100;
- const FieldTrial::Probability kProbability = 50; // 50% probability.
- FieldTrial* trial = new FieldTrial("IPv6_Probe", kDivisor);
- int skip_group = trial->AppendGroup("_IPv6_probe_skipped", kProbability);
- trial->AppendGroup("_IPv6_probe_done",
- FieldTrial::kAllRemainingProbability);
- bool use_ipv6_probe = (trial->group() != skip_group);
-
- // Perform probe, and then optionally use result to disable IPv6.
- // Some users report confused OS handling of IPv6, leading to large
- // latency. If we can show that IPv6 is not supported, then disabliing it
- // will work around such problems.
- if ((!net::IPv6Supported() && use_ipv6_probe) ||
- command_line.HasSwitch(switches::kDisableIPv6))
- global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
- }
+ hostname_remappings = StringPrintf("MAP * %s", host.c_str());
+ } else if (command_line.HasSwitch(switches::kHostResolverRules)) {
+ hostname_remappings =
+ command_line.GetSwitchValueASCII(switches::kHostResolverRules);
+ }
+
+ // If hostname remappings were specified on the command-line, layer these
+ // rules on top of the real host resolver. This allows forwarding all requests
+ // through a designated test server.
+ if (!hostname_remappings.empty()) {
+ net::MappedHostResolver* remapped_resolver =
+ new net::MappedHostResolver(global_host_resolver);
+ global_host_resolver = remapped_resolver;
+ remapped_resolver->SetRulesFromString(hostname_remappings);
}
return global_host_resolver;
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index eea71f7..c7de20f 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -353,6 +353,19 @@ const char kHideIcons[] = "hide-icons";
// that the UI tests don't depend on what comes up for http://google.com.
const char kHomePage[] = "homepage";
+// Comma separated list of rules that control how hostnames are resolved.
+//
+// For example:
+// "MAP * 127.0.0.1" --> Forces all hostnames to be resolved to 127.0.0.1
+// "MAP *.google.com proxy" --> Forces all google.com subdomains to be
+// resolved to "proxy".
+// "MAP test.com [::1]:77 --> Forces "test.com" to resolve to IPv6 loopback.
+// Will also force the port of the resulting
+// socket address to be 77.
+// "MAP * baz, EXCLUDE www.google.com" --> Remaps everything to "baz",
+// except for "www.google.com".
+const char kHostResolverRules[] = "host-resolver-rules";
+
// Perform importing from another browser. The value associated with this
// setting encodes the target browser and what items to import.
const char kImport[] = "import";
@@ -661,6 +674,7 @@ const char kUseSpdy[] = "use-spdy";
// From that point on, it is completely a static configuration.
// TODO(mbelshe): Remove this flag when testing is complete.
// --testing-fixed-host=myserver
+// TODO(eroman): Can this be replaced by host-resolver-rules ?
const char kFixedHost[] = "testing-fixed-host";
// These two flags are used to force http and https requests to fixed ports.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 5098ac0..365c0b4 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -112,6 +112,7 @@ extern const char kGpuLauncher[];
extern const char kGpuProcess[];
extern const char kHideIcons[];
extern const char kHomePage[];
+extern const char kHostResolverRules[];
extern const char kImport[];
extern const char kInProcessPlugins[];
extern const char kIncognito[];
diff --git a/net/base/fixed_host_resolver.cc b/net/base/fixed_host_resolver.cc
deleted file mode 100644
index 47089f1..0000000
--- a/net/base/fixed_host_resolver.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2009 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/fixed_host_resolver.h"
-
-#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
-#include "net/base/host_resolver_impl.h"
-
-namespace net {
-
-FixedHostResolver::FixedHostResolver(const std::string& host)
- : initialized_(false) {
- int port;
- std::string parsed_host;
- if (!ParseHostAndPort(host, &parsed_host, &port)) {
- LOG(DFATAL) << "Invalid FixedHostResolver information: " << host;
- return;
- }
-
- int rv = SystemHostResolverProc(host, net::ADDRESS_FAMILY_UNSPECIFIED,
- &address_);
- if (rv != OK) {
- LOG(ERROR) << "Could not resolve fixed host: " << host;
- return;
- }
-
- initialized_ = true;
-}
-
-int FixedHostResolver::Resolve(const RequestInfo& info,
- AddressList* addresses,
- CompletionCallback* callback,
- RequestHandle* out_req,
- LoadLog* load_log) {
- if (!initialized_)
- return ERR_NAME_NOT_RESOLVED;
-
- DCHECK(addresses);
- addresses->Copy(address_.head());
- addresses->SetPort(info.port());
- return OK;
-}
-
-} // namespace net
diff --git a/net/base/fixed_host_resolver.h b/net/base/fixed_host_resolver.h
deleted file mode 100644
index ee7b114..0000000
--- a/net/base/fixed_host_resolver.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2009 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.
-
-#ifndef NET_BASE_FIXED_HOST_RESOLVER_H_
-#define NET_BASE_FIXED_HOST_RESOLVER_H_
-
-#include <string>
-
-#include "net/base/address_list.h"
-#include "net/base/host_resolver.h"
-
-namespace net {
-
-// A FixedHostResolver resolves all addresses to a single address.
-class FixedHostResolver : public HostResolver {
- public:
- // |host| is a string representing the resolution.
- // example: foo.myproxy.com
- explicit FixedHostResolver(const std::string& host);
-
- // HostResolver methods:
- virtual int Resolve(const RequestInfo& info,
- AddressList* addresses,
- CompletionCallback* callback,
- RequestHandle* out_req,
- LoadLog* load_log);
- virtual void CancelRequest(RequestHandle req) {}
- virtual void AddObserver(Observer* observer) {}
- virtual void RemoveObserver(Observer* observer) {}
-
- private:
- ~FixedHostResolver() {}
-
- AddressList address_;
- bool initialized_;
-};
-
-} // namespace net
-
-#endif // NET_BASE_MOCK_HOST_RESOLVER_H_
diff --git a/net/base/host_resolver.h b/net/base/host_resolver.h
index a960805..da431f3 100644
--- a/net/base/host_resolver.h
+++ b/net/base/host_resolver.h
@@ -46,7 +46,14 @@ class HostResolver : public base::RefCountedThreadSafe<HostResolver> {
priority_(MEDIUM) {}
int port() const { return port_; }
+ void set_port(int port) {
+ port_ = port;
+ }
+
const std::string& hostname() const { return hostname_; }
+ void set_hostname(const std::string& hostname) {
+ hostname_ = hostname;
+ }
AddressFamily address_family() const { return address_family_; }
void set_address_family(AddressFamily address_family) {
diff --git a/net/base/mapped_host_resolver.cc b/net/base/mapped_host_resolver.cc
new file mode 100644
index 0000000..3624a9b
--- /dev/null
+++ b/net/base/mapped_host_resolver.cc
@@ -0,0 +1,111 @@
+// 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/mapped_host_resolver.h"
+
+#include "base/string_tokenizer.h"
+#include "base/string_util.h"
+#include "net/base/net_util.h"
+
+namespace net {
+
+MappedHostResolver::MappedHostResolver(HostResolver* impl)
+ : impl_(impl) {
+}
+
+int MappedHostResolver::Resolve(const RequestInfo& info,
+ AddressList* addresses,
+ CompletionCallback* callback,
+ RequestHandle* out_req,
+ LoadLog* load_log) {
+ // Modify the request before forwarding it to |impl_|.
+ RequestInfo modified_info = info;
+ RewriteRequest(&modified_info);
+ return impl_->Resolve(modified_info, addresses, callback, out_req, load_log);
+}
+
+void MappedHostResolver::CancelRequest(RequestHandle req) {
+ impl_->CancelRequest(req);
+}
+
+void MappedHostResolver::AddObserver(Observer* observer) {
+ impl_->AddObserver(observer);
+}
+
+void MappedHostResolver::RemoveObserver(Observer* observer) {
+ impl_->RemoveObserver(observer);
+}
+
+MappedHostResolver::~MappedHostResolver() {
+}
+
+bool MappedHostResolver::RewriteRequest(RequestInfo* info) 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 (MatchPatternASCII(info->hostname(), 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;
+
+ if (!MatchPatternASCII(info->hostname(), rule.hostname_pattern))
+ continue; // This rule doesn't apply.
+
+ info->set_hostname(rule.replacement_hostname);
+ if (rule.replacement_port != -1)
+ info->set_port(rule.replacement_port);
+ return true;
+ }
+
+ return false;
+}
+
+bool MappedHostResolver::AddRuleFromString(const std::string& rule_string) {
+ std::string trimmed;
+ TrimWhitespaceASCII(rule_string, TRIM_ALL, &trimmed);
+ std::vector<std::string> parts;
+ 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 MappedHostResolver::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
diff --git a/net/base/mapped_host_resolver.h b/net/base/mapped_host_resolver.h
new file mode 100644
index 0000000..af78a9c
--- /dev/null
+++ b/net/base/mapped_host_resolver.h
@@ -0,0 +1,79 @@
+// 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.
+
+#ifndef NET_BASE_MAPPED_HOST_RESOLVER_H_
+#define NET_BASE_MAPPED_HOST_RESOLVER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/ref_counted.h"
+#include "net/base/host_resolver.h"
+
+namespace net {
+
+// This class wraps an existing HostResolver instance, but modifies the
+// request before passing it off to |impl|. This is different from
+// MockHostResolver which does the remapping at the HostResolverProc
+// layer, so it is able to preserve the effectiveness of the cache.
+class MappedHostResolver : public HostResolver {
+ public:
+ // Creates a MappedHostResolver that forwards all of its requests through
+ // |impl|.
+ explicit MappedHostResolver(HostResolver* impl);
+
+ // HostResolver methods:
+ virtual int Resolve(const RequestInfo& info,
+ AddressList* addresses,
+ CompletionCallback* callback,
+ RequestHandle* out_req,
+ LoadLog* load_log);
+ virtual void CancelRequest(RequestHandle req);
+ virtual void AddObserver(Observer* observer);
+ virtual void RemoveObserver(Observer* observer);
+
+ // Adds a rule to this mapper. The format of the rule can be one of:
+ //
+ // "MAP" <hostname_pattern> <replacement_host> [":" <replacement_port>]
+ // "EXCLUDE" <hostname_pattern>
+ //
+ // The <replacement_host> can be either a hostname, or an IP address literal.
+ //
+ // Returns true if the rule was successfully parsed and added.
+ bool AddRuleFromString(const std::string& rule_string);
+
+ // Takes a comma separated list of rules, and assigns them to this resolver.
+ void SetRulesFromString(const std::string& rules_string);
+
+ private:
+ struct MapRule {
+ MapRule() : replacement_port(-1) {}
+
+ std::string hostname_pattern;
+ std::string replacement_hostname;
+ int replacement_port;
+ };
+
+ struct ExclusionRule {
+ std::string hostname_pattern;
+ };
+
+ typedef std::vector<MapRule> MapRuleList;
+ typedef std::vector<ExclusionRule> ExclusionRuleList;
+
+ virtual ~MappedHostResolver();
+
+ // Modifies |*info| based on the current rules. Returns true if the
+ // RequestInfo was modified, false otherwise.
+ bool RewriteRequest(RequestInfo* info) const;
+
+ scoped_refptr<HostResolver> impl_;
+
+ MapRuleList map_rules_;
+ ExclusionRuleList exclusion_rules_;
+};
+
+} // namespace net
+
+#endif // NET_BASE_MAPPED_HOST_RESOLVER_H_
diff --git a/net/base/mapped_host_resolver_unittest.cc b/net/base/mapped_host_resolver_unittest.cc
new file mode 100644
index 0000000..6da84e0
--- /dev/null
+++ b/net/base/mapped_host_resolver_unittest.cc
@@ -0,0 +1,148 @@
+// 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/mapped_host_resolver.h"
+
+#include "net/base/mock_host_resolver.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+TEST(MappedHostResolverTest, Inclusion) {
+ // Create a mock host resolver, with specific hostname to IP mappings.
+ scoped_refptr<MockHostResolver> resolver_impl = new MockHostResolver();
+ resolver_impl->rules()->AddSimulatedFailure("*google.com");
+ resolver_impl->rules()->AddRule("baz.com", "192.168.1.5");
+ resolver_impl->rules()->AddRule("foo.com", "192.168.1.8");
+ resolver_impl->rules()->AddRule("proxy", "192.168.1.11");
+
+ // Create a remapped resolver that uses |resolver_impl|.
+ scoped_refptr<MappedHostResolver> resolver =
+ new MappedHostResolver(resolver_impl);
+
+ int rv;
+ AddressList address_list;
+
+ // Try resolving "www.google.com:80". There are no mappings yet, so this
+ // hits |resolver_impl| and fails.
+ rv = resolver->Resolve(HostResolver::RequestInfo("www.google.com", 80),
+ &address_list, NULL, NULL, NULL);
+ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
+
+ // Remap *.google.com to baz.com.
+ EXPECT_TRUE(resolver->AddRuleFromString("map *.google.com baz.com"));
+
+ // Try resolving "www.google.com:80". Should be remapped to "baz.com:80".
+ rv = resolver->Resolve(HostResolver::RequestInfo("www.google.com", 80),
+ &address_list, NULL, NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("192.168.1.5", NetAddressToString(address_list.head()));
+ EXPECT_EQ(80, address_list.GetPort());
+
+ // Try resolving "foo.com:77". This will NOT be remapped, so result
+ // is "foo.com:77".
+ rv = resolver->Resolve(HostResolver::RequestInfo("foo.com", 77),
+ &address_list, NULL, NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("192.168.1.8", NetAddressToString(address_list.head()));
+ EXPECT_EQ(77, address_list.GetPort());
+
+ // Remap "*.org" to "proxy:99".
+ EXPECT_TRUE(resolver->AddRuleFromString("Map *.org proxy:99"));
+
+ // Try resolving "chromium.org:61". Should be remapped to "proxy:99".
+ rv = resolver->Resolve(HostResolver::RequestInfo("chromium.org", 61),
+ &address_list, NULL, NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("192.168.1.11", NetAddressToString(address_list.head()));
+ EXPECT_EQ(99, address_list.GetPort());
+}
+
+// Tests that exclusions are respected.
+TEST(MappedHostResolverTest, Exclusion) {
+ // Create a mock host resolver, with specific hostname to IP mappings.
+ scoped_refptr<MockHostResolver> resolver_impl = new MockHostResolver();
+ resolver_impl->rules()->AddRule("baz", "192.168.1.5");
+ resolver_impl->rules()->AddRule("www.google.com", "192.168.1.3");
+
+ // Create a remapped resolver that uses |resolver_impl|.
+ scoped_refptr<MappedHostResolver> resolver =
+ new MappedHostResolver(resolver_impl);
+
+ int rv;
+ AddressList address_list;
+
+ // Remap "*.com" to "baz".
+ EXPECT_TRUE(resolver->AddRuleFromString("map *.com baz"));
+
+ // Add an exclusion for "*.google.com".
+ EXPECT_TRUE(resolver->AddRuleFromString("EXCLUDE *.google.com"));
+
+ // Try resolving "www.google.com". Should not be remapped due to exclusion).
+ rv = resolver->Resolve(HostResolver::RequestInfo("www.google.com", 80),
+ &address_list, NULL, NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("192.168.1.3", NetAddressToString(address_list.head()));
+ EXPECT_EQ(80, address_list.GetPort());
+
+ // Try resolving "chrome.com:80". Should be remapped to "baz:80".
+ rv = resolver->Resolve(HostResolver::RequestInfo("chrome.com", 80),
+ &address_list, NULL, NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("192.168.1.5", NetAddressToString(address_list.head()));
+ EXPECT_EQ(80, address_list.GetPort());
+}
+
+TEST(MappedHostResolverTest, SetRulesFromString) {
+ // Create a mock host resolver, with specific hostname to IP mappings.
+ scoped_refptr<MockHostResolver> resolver_impl = new MockHostResolver();
+ resolver_impl->rules()->AddRule("baz", "192.168.1.7");
+ resolver_impl->rules()->AddRule("bar", "192.168.1.9");
+
+ // Create a remapped resolver that uses |resolver_impl|.
+ scoped_refptr<MappedHostResolver> resolver =
+ new MappedHostResolver(resolver_impl);
+
+ int rv;
+ AddressList address_list;
+
+ // Remap "*.com" to "baz", and *.net to "bar:60".
+ resolver->SetRulesFromString("map *.com baz , map *.net bar:60");
+
+ // Try resolving "www.google.com". Should be remapped to "baz".
+ rv = resolver->Resolve(HostResolver::RequestInfo("www.google.com", 80),
+ &address_list, NULL, NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("192.168.1.7", NetAddressToString(address_list.head()));
+ EXPECT_EQ(80, address_list.GetPort());
+
+ // Try resolving "chrome.net:80". Should be remapped to "bar:60".
+ rv = resolver->Resolve(HostResolver::RequestInfo("chrome.net", 80),
+ &address_list, NULL, NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("192.168.1.9", NetAddressToString(address_list.head()));
+ EXPECT_EQ(60, address_list.GetPort());
+}
+
+// Parsing bad rules should silently discard the rule (and never crash).
+TEST(MappedHostResolverTest, ParseInvalidRules) {
+ scoped_refptr<MappedHostResolver> resolver = new MappedHostResolver(NULL);
+
+ EXPECT_FALSE(resolver->AddRuleFromString("xyz"));
+ EXPECT_FALSE(resolver->AddRuleFromString(""));
+ EXPECT_FALSE(resolver->AddRuleFromString(" "));
+ EXPECT_FALSE(resolver->AddRuleFromString("EXCLUDE"));
+ EXPECT_FALSE(resolver->AddRuleFromString("EXCLUDE foo bar"));
+ EXPECT_FALSE(resolver->AddRuleFromString("INCLUDE"));
+ EXPECT_FALSE(resolver->AddRuleFromString("INCLUDE x"));
+ EXPECT_FALSE(resolver->AddRuleFromString("INCLUDE x :10"));
+}
+
+} // namespace
+
+} // namespace net
diff --git a/net/net.gyp b/net/net.gyp
index b6f6062..599f683 100755
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -58,8 +58,6 @@
'base/file_stream_win.cc',
'base/filter.cc',
'base/filter.h',
- 'base/fixed_host_resolver.cc',
- 'base/fixed_host_resolver.h',
'base/gzip_filter.cc',
'base/gzip_filter.h',
'base/gzip_header.cc',
@@ -89,6 +87,8 @@
'base/load_log_util.cc',
'base/load_log_util.h',
'base/load_states.h',
+ 'base/mapped_host_resolver.cc',
+ 'base/mapped_host_resolver.h',
'base/mime_sniffer.cc',
'base/mime_sniffer.h',
'base/mime_util.cc',
@@ -600,6 +600,7 @@
'base/load_log_util_unittest.cc',
'base/listen_socket_unittest.cc',
'base/listen_socket_unittest.h',
+ 'base/mapped_host_resolver_unittest.cc',
'base/mime_sniffer_unittest.cc',
'base/mime_util_unittest.cc',
'base/mock_network_change_notifier.h',