| // Copyright (c) 2012 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/address_list.h" |
| #include "net/base/mock_host_resolver.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/net_log.h" |
| #include "net/base/net_util.h" |
| #include "net/base/test_completion_callback.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace net { |
| |
| namespace { |
| |
| std::string FirstAddress(const AddressList& address_list) { |
| if (address_list.empty()) |
| return ""; |
| return address_list.front().ToString(); |
| } |
| |
| TEST(MappedHostResolverTest, Inclusion) { |
| // Create a mock host resolver, with specific hostname to IP mappings. |
| scoped_ptr<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_ptr<MappedHostResolver> resolver( |
| new MappedHostResolver(resolver_impl.PassAs<HostResolver>())); |
| |
| int rv; |
| AddressList address_list; |
| |
| // Try resolving "www.google.com:80". There are no mappings yet, so this |
| // hits |resolver_impl| and fails. |
| TestCompletionCallback callback; |
| rv = resolver->Resolve(HostResolver::RequestInfo( |
| HostPortPair("www.google.com", 80)), |
| &address_list, callback.callback(), NULL, |
| BoundNetLog()); |
| EXPECT_EQ(ERR_IO_PENDING, rv); |
| rv = callback.WaitForResult(); |
| 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( |
| HostPortPair("www.google.com", 80)), |
| &address_list, callback.callback(), NULL, |
| BoundNetLog()); |
| EXPECT_EQ(ERR_IO_PENDING, rv); |
| rv = callback.WaitForResult(); |
| EXPECT_EQ(OK, rv); |
| EXPECT_EQ("192.168.1.5:80", FirstAddress(address_list)); |
| |
| // Try resolving "foo.com:77". This will NOT be remapped, so result |
| // is "foo.com:77". |
| rv = resolver->Resolve(HostResolver::RequestInfo(HostPortPair("foo.com", 77)), |
| &address_list, callback.callback(), NULL, |
| BoundNetLog()); |
| EXPECT_EQ(ERR_IO_PENDING, rv); |
| rv = callback.WaitForResult(); |
| EXPECT_EQ(OK, rv); |
| EXPECT_EQ("192.168.1.8:77", FirstAddress(address_list)); |
| |
| // 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 |
| (HostPortPair("chromium.org", 61)), |
| &address_list, callback.callback(), NULL, |
| BoundNetLog()); |
| EXPECT_EQ(ERR_IO_PENDING, rv); |
| rv = callback.WaitForResult(); |
| EXPECT_EQ(OK, rv); |
| EXPECT_EQ("192.168.1.11:99", FirstAddress(address_list)); |
| } |
| |
| // Tests that exclusions are respected. |
| TEST(MappedHostResolverTest, Exclusion) { |
| // Create a mock host resolver, with specific hostname to IP mappings. |
| scoped_ptr<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_ptr<MappedHostResolver> resolver( |
| new MappedHostResolver(resolver_impl.PassAs<HostResolver>())); |
| |
| int rv; |
| AddressList address_list; |
| TestCompletionCallback callback; |
| |
| // 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( |
| HostPortPair("www.google.com", 80)), |
| &address_list, callback.callback(), NULL, |
| BoundNetLog()); |
| EXPECT_EQ(ERR_IO_PENDING, rv); |
| rv = callback.WaitForResult(); |
| EXPECT_EQ(OK, rv); |
| EXPECT_EQ("192.168.1.3:80", FirstAddress(address_list)); |
| |
| // Try resolving "chrome.com:80". Should be remapped to "baz:80". |
| rv = resolver->Resolve(HostResolver::RequestInfo( |
| HostPortPair("chrome.com", 80)), |
| &address_list, callback.callback(), NULL, |
| BoundNetLog()); |
| EXPECT_EQ(ERR_IO_PENDING, rv); |
| rv = callback.WaitForResult(); |
| EXPECT_EQ(OK, rv); |
| EXPECT_EQ("192.168.1.5:80", FirstAddress(address_list)); |
| } |
| |
| TEST(MappedHostResolverTest, SetRulesFromString) { |
| // Create a mock host resolver, with specific hostname to IP mappings. |
| scoped_ptr<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_ptr<MappedHostResolver> resolver( |
| new MappedHostResolver(resolver_impl.PassAs<HostResolver>())); |
| |
| int rv; |
| AddressList address_list; |
| TestCompletionCallback callback; |
| |
| // 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( |
| HostPortPair("www.google.com", 80)), |
| &address_list, callback.callback(), NULL, |
| BoundNetLog()); |
| EXPECT_EQ(ERR_IO_PENDING, rv); |
| rv = callback.WaitForResult(); |
| EXPECT_EQ(OK, rv); |
| EXPECT_EQ("192.168.1.7:80", FirstAddress(address_list)); |
| |
| // Try resolving "chrome.net:80". Should be remapped to "bar:60". |
| rv = resolver->Resolve(HostResolver::RequestInfo( |
| HostPortPair("chrome.net", 80)), |
| &address_list, callback.callback(), NULL, |
| BoundNetLog()); |
| EXPECT_EQ(ERR_IO_PENDING, rv); |
| rv = callback.WaitForResult(); |
| EXPECT_EQ(OK, rv); |
| EXPECT_EQ("192.168.1.9:60", FirstAddress(address_list)); |
| } |
| |
| // Parsing bad rules should silently discard the rule (and never crash). |
| TEST(MappedHostResolverTest, ParseInvalidRules) { |
| scoped_ptr<MappedHostResolver> resolver( |
| new MappedHostResolver(scoped_ptr<HostResolver>())); |
| |
| 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 |