| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/mock_host_resolver.h" | 5 #include "net/base/mock_host_resolver.h" |
| 6 | 6 |
| 7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
| 8 #include "base/platform_thread.h" | 8 #include "base/platform_thread.h" |
| 9 #include "base/ref_counted.h" | 9 #include "base/ref_counted.h" |
| 10 #include "googleurl/src/url_canon_ip.h" |
| 10 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 11 | 12 |
| 12 namespace net { | 13 namespace net { |
| 13 | 14 |
| 15 namespace { |
| 16 // Fills |addrlist| with a socket address for |host| which should be an |
| 17 // IPv6 literal. Returns OK on success. |
| 18 int ResolveIPV6LiteralUsingGURL(const std::string& host, |
| 19 AddressList* addrlist) { |
| 20 // GURL expects the hostname to be surrounded with brackets. |
| 21 std::string host_brackets = "[" + host + "]"; |
| 22 url_parse::Component host_comp(0, host_brackets.size()); |
| 23 |
| 24 // Try parsing the hostname as an IPv6 literal. |
| 25 unsigned char ipv6_addr[16]; // 128 bits. |
| 26 bool ok = url_canon::IPv6AddressToNumber(host_brackets.data(), |
| 27 host_comp, |
| 28 ipv6_addr); |
| 29 if (!ok) { |
| 30 LOG(WARNING) << "Not an IPv6 literal: " << host; |
| 31 return ERR_UNEXPECTED; |
| 32 } |
| 33 |
| 34 *addrlist = AddressList::CreateIPv6Address(ipv6_addr); |
| 35 return OK; |
| 36 } |
| 37 |
| 38 } // namespace |
| 39 |
| 14 MockHostResolverBase::MockHostResolverBase(bool use_caching) | 40 MockHostResolverBase::MockHostResolverBase(bool use_caching) |
| 15 : use_caching_(use_caching) { | 41 : use_caching_(use_caching) { |
| 16 Reset(NULL); | 42 Reset(NULL); |
| 17 } | 43 } |
| 18 | 44 |
| 19 int MockHostResolverBase::Resolve(const RequestInfo& info, | 45 int MockHostResolverBase::Resolve(const RequestInfo& info, |
| 20 AddressList* addresses, | 46 AddressList* addresses, |
| 21 CompletionCallback* callback, | 47 CompletionCallback* callback, |
| 22 RequestHandle* out_req) { | 48 RequestHandle* out_req) { |
| 23 if (synchronous_mode_) { | 49 if (synchronous_mode_) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 | 90 |
| 65 int max_cache_entries = use_caching_ ? 100 : 0; | 91 int max_cache_entries = use_caching_ ? 100 : 0; |
| 66 int max_cache_age_ms = use_caching_ ? 60000 : 0; | 92 int max_cache_age_ms = use_caching_ ? 60000 : 0; |
| 67 | 93 |
| 68 impl_ = new HostResolverImpl(proc, max_cache_entries, max_cache_age_ms); | 94 impl_ = new HostResolverImpl(proc, max_cache_entries, max_cache_age_ms); |
| 69 } | 95 } |
| 70 | 96 |
| 71 //----------------------------------------------------------------------------- | 97 //----------------------------------------------------------------------------- |
| 72 | 98 |
| 73 struct RuleBasedHostResolverProc::Rule { | 99 struct RuleBasedHostResolverProc::Rule { |
| 100 enum ResolverType { |
| 101 kResolverTypeFail, |
| 102 kResolverTypeSystem, |
| 103 kResolverTypeIPV6Literal, |
| 104 }; |
| 105 |
| 106 ResolverType resolver_type; |
| 74 std::string host_pattern; | 107 std::string host_pattern; |
| 75 std::string replacement; | 108 std::string replacement; |
| 76 int latency_ms; // In milliseconds. | 109 int latency_ms; // In milliseconds. |
| 77 bool direct; // if true, don't mangle hostname and ignore replacement | 110 |
| 78 Rule(const std::string& host_pattern, const std::string& replacement) | 111 Rule(ResolverType resolver_type, |
| 79 : host_pattern(host_pattern), | 112 const std::string& host_pattern, |
| 113 const std::string& replacement, |
| 114 int latency_ms) |
| 115 : resolver_type(resolver_type), |
| 116 host_pattern(host_pattern), |
| 80 replacement(replacement), | 117 replacement(replacement), |
| 81 latency_ms(0), | 118 latency_ms(latency_ms) {} |
| 82 direct(false) {} | |
| 83 Rule(const std::string& host_pattern, const std::string& replacement, | |
| 84 const int latency_ms) | |
| 85 : host_pattern(host_pattern), | |
| 86 replacement(replacement), | |
| 87 latency_ms(latency_ms), | |
| 88 direct(false) {} | |
| 89 Rule(const std::string& host_pattern, const std::string& replacement, | |
| 90 const bool direct) | |
| 91 : host_pattern(host_pattern), | |
| 92 replacement(replacement), | |
| 93 latency_ms(0), | |
| 94 direct(direct) {} | |
| 95 }; | 119 }; |
| 96 | 120 |
| 97 RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous) | 121 RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous) |
| 98 : HostResolverProc(previous) { | 122 : HostResolverProc(previous) { |
| 99 } | 123 } |
| 100 | 124 |
| 101 RuleBasedHostResolverProc::~RuleBasedHostResolverProc() { | 125 RuleBasedHostResolverProc::~RuleBasedHostResolverProc() { |
| 102 } | 126 } |
| 103 | 127 |
| 104 void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern, | 128 void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern, |
| 105 const std::string& replacement) { | 129 const std::string& replacement) { |
| 106 rules_.push_back(Rule(host_pattern, replacement)); | 130 DCHECK(!replacement.empty()); |
| 131 Rule rule(Rule::kResolverTypeSystem, host_pattern, replacement, 0); |
| 132 rules_.push_back(rule); |
| 133 } |
| 134 |
| 135 void RuleBasedHostResolverProc::AddIPv6Rule(const std::string& host_pattern, |
| 136 const std::string& ipv6_literal) { |
| 137 Rule rule(Rule::kResolverTypeIPV6Literal, host_pattern, ipv6_literal, 0); |
| 138 rules_.push_back(rule); |
| 107 } | 139 } |
| 108 | 140 |
| 109 void RuleBasedHostResolverProc::AddRuleWithLatency( | 141 void RuleBasedHostResolverProc::AddRuleWithLatency( |
| 110 const std::string& host_pattern, | 142 const std::string& host_pattern, |
| 111 const std::string& replacement, int latency_ms) { | 143 const std::string& replacement, |
| 112 rules_.push_back(Rule(host_pattern, replacement, latency_ms)); | 144 int latency_ms) { |
| 145 DCHECK(!replacement.empty()); |
| 146 Rule rule(Rule::kResolverTypeSystem, host_pattern, replacement, latency_ms); |
| 147 rules_.push_back(rule); |
| 113 } | 148 } |
| 114 | 149 |
| 115 void RuleBasedHostResolverProc::AllowDirectLookup(const std::string& host) { | 150 void RuleBasedHostResolverProc::AllowDirectLookup( |
| 116 rules_.push_back(Rule(host, "", true)); | 151 const std::string& host_pattern) { |
| 152 Rule rule(Rule::kResolverTypeSystem, host_pattern, "", 0); |
| 153 rules_.push_back(rule); |
| 117 } | 154 } |
| 118 | 155 |
| 119 void RuleBasedHostResolverProc::AddSimulatedFailure(const std::string& host) { | 156 void RuleBasedHostResolverProc::AddSimulatedFailure( |
| 120 AddRule(host, ""); | 157 const std::string& host_pattern) { |
| 158 Rule rule(Rule::kResolverTypeFail, host_pattern, "", 0); |
| 159 rules_.push_back(rule); |
| 121 } | 160 } |
| 122 | 161 |
| 123 int RuleBasedHostResolverProc::Resolve(const std::string& host, | 162 int RuleBasedHostResolverProc::Resolve(const std::string& host, |
| 124 AddressList* addrlist) { | 163 AddressList* addrlist) { |
| 125 RuleList::iterator r; | 164 RuleList::iterator r; |
| 126 for (r = rules_.begin(); r != rules_.end(); ++r) { | 165 for (r = rules_.begin(); r != rules_.end(); ++r) { |
| 127 if (MatchPattern(host, r->host_pattern)) { | 166 if (MatchPattern(host, r->host_pattern)) { |
| 128 if (r->latency_ms != 0) { | 167 if (r->latency_ms != 0) { |
| 129 PlatformThread::Sleep(r->latency_ms); | 168 PlatformThread::Sleep(r->latency_ms); |
| 130 // Hmm, this seems unecessary. | 169 // Hmm, this seems unecessary. |
| 131 r->latency_ms = 1; | 170 r->latency_ms = 1; |
| 132 } | 171 } |
| 133 const std::string& effective_host = r->direct ? host : r->replacement; | 172 |
| 134 if (effective_host.empty()) | 173 // Remap to a new host. |
| 135 return ERR_NAME_NOT_RESOLVED; | 174 const std::string& effective_host = |
| 136 return SystemHostResolverProc(effective_host, addrlist); | 175 r->replacement.empty() ? host : r->replacement; |
| 176 |
| 177 // Apply the resolving function to the remapped hostname. |
| 178 switch (r->resolver_type) { |
| 179 case Rule::kResolverTypeFail: |
| 180 return ERR_NAME_NOT_RESOLVED; |
| 181 case Rule::kResolverTypeSystem: |
| 182 return SystemHostResolverProc(effective_host, addrlist); |
| 183 case Rule::kResolverTypeIPV6Literal: |
| 184 return ResolveIPV6LiteralUsingGURL(effective_host, addrlist); |
| 185 default: |
| 186 NOTREACHED(); |
| 187 return ERR_UNEXPECTED; |
| 188 } |
| 137 } | 189 } |
| 138 } | 190 } |
| 139 return ResolveUsingPrevious(host, addrlist); | 191 return ResolveUsingPrevious(host, addrlist); |
| 140 } | 192 } |
| 141 | 193 |
| 142 //----------------------------------------------------------------------------- | 194 //----------------------------------------------------------------------------- |
| 143 | 195 |
| 144 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc( | 196 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc( |
| 145 HostResolverProc* proc) : current_proc_(proc) { | 197 HostResolverProc* proc) : current_proc_(proc) { |
| 146 previous_proc_ = HostResolverProc::SetDefault(current_proc_); | 198 previous_proc_ = HostResolverProc::SetDefault(current_proc_); |
| 147 current_proc_->set_previous_proc(previous_proc_); | 199 current_proc_->set_previous_proc(previous_proc_); |
| 148 } | 200 } |
| 149 | 201 |
| 150 ScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() { | 202 ScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() { |
| 151 HostResolverProc* old_proc = HostResolverProc::SetDefault(previous_proc_); | 203 HostResolverProc* old_proc = HostResolverProc::SetDefault(previous_proc_); |
| 152 // The lifetimes of multiple instances must be nested. | 204 // The lifetimes of multiple instances must be nested. |
| 153 CHECK(old_proc == current_proc_); | 205 CHECK(old_proc == current_proc_); |
| 154 } | 206 } |
| 155 | 207 |
| 156 void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) { | 208 void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) { |
| 157 current_proc_ = proc; | 209 current_proc_ = proc; |
| 158 previous_proc_ = HostResolverProc::SetDefault(current_proc_); | 210 previous_proc_ = HostResolverProc::SetDefault(current_proc_); |
| 159 current_proc_->set_previous_proc(previous_proc_); | 211 current_proc_->set_previous_proc(previous_proc_); |
| 160 } | 212 } |
| 161 | 213 |
| 162 } // namespace net | 214 } // namespace net |
| OLD | NEW |