summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 22:47:14 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 22:47:14 +0000
commitb6a50183e21e21207f2dff4953d19aa5be62d166 (patch)
tree9a937074af7bb0c5ff9c1987f68a4055bb54762c /net
parent6402aaec3c045969b60ef7b782ce25992d07a70f (diff)
downloadchromium_src-b6a50183e21e21207f2dff4953d19aa5be62d166.zip
chromium_src-b6a50183e21e21207f2dff4953d19aa5be62d166.tar.gz
chromium_src-b6a50183e21e21207f2dff4953d19aa5be62d166.tar.bz2
Add --host-rules support.
The format for --host-rules is identical to --host-resolver-rules. The difference is that --host-rules affects the endpoint of the HttpNetworkTransaction, not just the host resolver. So, this means the host passed to the host resolver and the TCP connect(), the tunnel CONNECT, and the SOCKS connect will be different. Review URL: http://codereview.chromium.org/2057007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47083 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/host_mapping_rules.cc85
-rw-r--r--net/base/host_mapping_rules.h61
-rw-r--r--net/base/host_mapping_rules_unittest.cc56
-rw-r--r--net/base/mapped_host_resolver.cc75
-rw-r--r--net/base/mapped_host_resolver.h31
-rw-r--r--net/http/http_network_transaction.cc29
-rw-r--r--net/http/http_network_transaction.h2
-rw-r--r--net/net.gyp3
8 files changed, 242 insertions, 100 deletions
diff --git a/net/base/host_mapping_rules.cc b/net/base/host_mapping_rules.cc
new file mode 100644
index 0000000..3296b0e
--- /dev/null
+++ b/net/base/host_mapping_rules.cc
@@ -0,0 +1,85 @@
+// 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_tokenizer.h"
+#include "base/string_util.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/net_util.h"
+
+namespace net {
+
+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 (MatchPatternASCII(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;
+
+ if (!MatchPatternASCII(host_port->host, rule.hostname_pattern))
+ continue; // This rule doesn't apply.
+
+ host_port->host = rule.replacement_hostname;
+ if (rule.replacement_port != -1)
+ host_port->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;
+ 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
diff --git a/net/base/host_mapping_rules.h b/net/base/host_mapping_rules.h
new file mode 100644
index 0000000..a754a47
--- /dev/null
+++ b/net/base/host_mapping_rules.h
@@ -0,0 +1,61 @@
+// 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_HOST_MAPPING_RULES_H_
+#define NET_BASE_HOST_MAPPING_RULES_H_
+
+#include <string>
+#include <vector>
+#include "base/basictypes.h"
+
+namespace net {
+
+struct HostPortPair;
+
+class HostMappingRules {
+ public:
+ HostMappingRules();
+
+ // Modifies |*host_port| based on the current rules. Returns true if the
+ // RequestInfo was modified, false otherwise.
+ bool RewriteHost(HostPortPair* host_port) const;
+
+ // 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);
+
+ // Sets the rules from a comma separated list of rules.
+ 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;
+
+ MapRuleList map_rules_;
+ ExclusionRuleList exclusion_rules_;
+
+ DISALLOW_COPY_AND_ASSIGN(HostMappingRules);
+};
+
+} // namespace net
+
+#endif // NET_BASE_HOST_MAPPING_RULES_H_
diff --git a/net/base/host_mapping_rules_unittest.cc b/net/base/host_mapping_rules_unittest.cc
new file mode 100644
index 0000000..0cea821
--- /dev/null
+++ b/net/base/host_mapping_rules_unittest.cc
@@ -0,0 +1,56 @@
+// 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 "net/base/host_port_pair.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+TEST(HostMappingRulesTest, SetRulesFromString) {
+ HostMappingRules rules;
+ rules.SetRulesFromString(
+ "map *.com baz , map *.net bar:60, EXCLUDE *.foo.com");
+
+ HostPortPair host_port("test", 1234);
+ EXPECT_FALSE(rules.RewriteHost(&host_port));
+ EXPECT_EQ("test", host_port.host);
+ EXPECT_EQ(1234u, host_port.port);
+
+ host_port = HostPortPair("chrome.net", 80);
+ EXPECT_TRUE(rules.RewriteHost(&host_port));
+ EXPECT_EQ("bar", host_port.host);
+ EXPECT_EQ(60u, host_port.port);
+
+ host_port = HostPortPair("crack.com", 80);
+ EXPECT_TRUE(rules.RewriteHost(&host_port));
+ EXPECT_EQ("baz", host_port.host);
+ EXPECT_EQ(80u, host_port.port);
+
+ host_port = HostPortPair("wtf.foo.com", 666);
+ EXPECT_FALSE(rules.RewriteHost(&host_port));
+ EXPECT_EQ("wtf.foo.com", host_port.host);
+ EXPECT_EQ(666u, host_port.port);
+}
+
+// Parsing bad rules should silently discard the rule (and never crash).
+TEST(HostMappingRulesTest, ParseInvalidRules) {
+ HostMappingRules rules;
+
+ EXPECT_FALSE(rules.AddRuleFromString("xyz"));
+ EXPECT_FALSE(rules.AddRuleFromString(""));
+ EXPECT_FALSE(rules.AddRuleFromString(" "));
+ EXPECT_FALSE(rules.AddRuleFromString("EXCLUDE"));
+ EXPECT_FALSE(rules.AddRuleFromString("EXCLUDE foo bar"));
+ EXPECT_FALSE(rules.AddRuleFromString("INCLUDE"));
+ EXPECT_FALSE(rules.AddRuleFromString("INCLUDE x"));
+ EXPECT_FALSE(rules.AddRuleFromString("INCLUDE x :10"));
+}
+
+} // namespace
+
+} // namespace net
diff --git a/net/base/mapped_host_resolver.cc b/net/base/mapped_host_resolver.cc
index fdd9de7..b401917 100644
--- a/net/base/mapped_host_resolver.cc
+++ b/net/base/mapped_host_resolver.cc
@@ -6,6 +6,7 @@
#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 {
@@ -21,7 +22,11 @@ int MappedHostResolver::Resolve(const RequestInfo& info,
const BoundNetLog& net_log) {
// Modify the request before forwarding it to |impl_|.
RequestInfo modified_info = info;
- RewriteRequest(&modified_info);
+ HostPortPair host_port(info.hostname(), info.port());
+ if (rules_.RewriteHost(&host_port)) {
+ modified_info.set_hostname(host_port.host);
+ modified_info.set_port(host_port.port);
+ }
return impl_->Resolve(modified_info, addresses, callback, out_req, net_log);
}
@@ -44,72 +49,4 @@ HostResolverImpl* MappedHostResolver::GetAsHostResolverImpl() {
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
index 7339f06..3229209 100644
--- a/net/base/mapped_host_resolver.h
+++ b/net/base/mapped_host_resolver.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/ref_counted.h"
+#include "net/base/host_mapping_rules.h"
#include "net/base/host_resolver.h"
namespace net {
@@ -42,37 +43,21 @@ class MappedHostResolver : public HostResolver {
// 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);
+ bool AddRuleFromString(const std::string& rule_string) {
+ return rules_.AddRuleFromString(rule_string);
+ }
// Takes a comma separated list of rules, and assigns them to this resolver.
- void SetRulesFromString(const std::string& rules_string);
+ void SetRulesFromString(const std::string& rules_string) {
+ rules_.SetRulesFromString(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_;
+ HostMappingRules rules_;
};
} // namespace net
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 2381450..6ac135e 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -17,6 +17,7 @@
#include "build/build_config.h"
#include "googleurl/src/gurl.h"
#include "net/base/connection_type_histograms.h"
+#include "net/base/host_mapping_rules.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
@@ -48,6 +49,7 @@ namespace net {
namespace {
+const HostMappingRules* g_host_mapping_rules = NULL;
const std::string* g_next_protos = NULL;
bool g_use_alternate_protocols = false;
@@ -194,16 +196,20 @@ void ProcessAlternateProtocol(const HttpResponseHeaders& headers,
return;
}
- if (alternate_protocols->HasAlternateProtocolFor(http_host_port_pair)) {
+ HostPortPair host_port(http_host_port_pair);
+ if (g_host_mapping_rules)
+ g_host_mapping_rules->RewriteHost(&host_port);
+
+ if (alternate_protocols->HasAlternateProtocolFor(host_port)) {
const HttpAlternateProtocols::PortProtocolPair existing_alternate =
- alternate_protocols->GetAlternateProtocolFor(http_host_port_pair);
+ alternate_protocols->GetAlternateProtocolFor(host_port);
// If we think the alternate protocol is broken, don't change it.
if (existing_alternate.protocol == HttpAlternateProtocols::BROKEN)
return;
}
alternate_protocols->SetAlternateProtocolFor(
- http_host_port_pair, port, HttpAlternateProtocols::NPN_SPDY_1);
+ host_port, port, HttpAlternateProtocols::NPN_SPDY_1);
}
class NetLogHttpRequestParameter : public NetLog::EventParameters {
@@ -302,6 +308,14 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session)
}
// static
+void HttpNetworkTransaction::SetHostMappingRules(const std::string& rules) {
+ HostMappingRules* host_mapping_rules = new HostMappingRules();
+ host_mapping_rules->SetRulesFromString(rules);
+ delete g_host_mapping_rules;
+ g_host_mapping_rules = host_mapping_rules;
+}
+
+// static
void HttpNetworkTransaction::SetUseAlternateProtocols(bool value) {
g_use_alternate_protocols = value;
}
@@ -725,6 +739,9 @@ int HttpNetworkTransaction::DoResolveProxy() {
endpoint_ = HostPortPair(request_->url.HostNoBrackets(),
request_->url.EffectiveIntPort());
+ if (g_host_mapping_rules)
+ g_host_mapping_rules->RewriteHost(&endpoint_);
+
GURL alternate_endpoint;
if (alternate_protocol_mode_ == kUnspecified) {
@@ -1232,12 +1249,8 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
return OK;
}
- HostPortPair http_host_port_pair;
- http_host_port_pair.host = request_->url.HostNoBrackets();
- http_host_port_pair.port = request_->url.EffectiveIntPort();
-
ProcessAlternateProtocol(*response_.headers,
- http_host_port_pair,
+ endpoint_,
session_->mutable_alternate_protocols());
int rv = HandleAuthChallenge();
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h
index 7b033e3..d9fed35 100644
--- a/net/http/http_network_transaction.h
+++ b/net/http/http_network_transaction.h
@@ -42,6 +42,8 @@ class HttpNetworkTransaction : public HttpTransaction {
virtual ~HttpNetworkTransaction();
+ static void SetHostMappingRules(const std::string& rules);
+
// Controls whether or not we use the Alternate-Protocol header.
static void SetUseAlternateProtocols(bool value);
diff --git a/net/net.gyp b/net/net.gyp
index d9c85f9..9fb28ce 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -66,6 +66,8 @@
'base/gzip_header.h',
'base/host_cache.cc',
'base/host_cache.h',
+ 'base/host_mapping_rules.cc',
+ 'base/host_mapping_rules.h',
'base/host_port_pair.cc',
'base/host_port_pair.h',
'base/host_resolver.cc',
@@ -621,6 +623,7 @@
'base/filter_unittest.h',
'base/gzip_filter_unittest.cc',
'base/host_cache_unittest.cc',
+ 'base/host_mapping_rules_unittest.cc',
'base/host_resolver_impl_unittest.cc',
'base/keygen_handler_unittest.cc',
'base/leak_annotations.h',