Move pending tile priorities to active on tree activation
[chromium-blink-merge.git] / net / base / mock_host_resolver.cc
bloba0835b88126f34eb64f1678a0ca3fc2707efde14
1 // Copyright (c) 2012 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/mock_host_resolver.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/message_loop.h"
13 #include "base/stl_util.h"
14 #include "base/string_split.h"
15 #include "base/string_util.h"
16 #include "base/threading/platform_thread.h"
17 #include "net/base/host_cache.h"
18 #include "net/base/net_errors.h"
19 #include "net/base/net_util.h"
20 #include "net/base/test_completion_callback.h"
21 #if defined(OS_WIN)
22 #include "net/base/winsock_init.h"
23 #endif
25 namespace net {
27 namespace {
29 // Cache size for the MockCachingHostResolver.
30 const unsigned kMaxCacheEntries = 100;
31 // TTL for the successful resolutions. Failures are not cached.
32 const unsigned kCacheEntryTTLSeconds = 60;
34 } // namespace
36 int ParseAddressList(const std::string& host_list,
37 const std::string& canonical_name,
38 AddressList* addrlist) {
39 *addrlist = AddressList();
40 std::vector<std::string> addresses;
41 base::SplitString(host_list, ',', &addresses);
42 addrlist->set_canonical_name(canonical_name);
43 for (size_t index = 0; index < addresses.size(); ++index) {
44 IPAddressNumber ip_number;
45 if (!ParseIPLiteralToNumber(addresses[index], &ip_number)) {
46 LOG(WARNING) << "Not a supported IP literal: " << addresses[index];
47 return ERR_UNEXPECTED;
49 addrlist->push_back(IPEndPoint(ip_number, -1));
51 return OK;
54 struct MockHostResolverBase::Request {
55 Request(const RequestInfo& req_info,
56 AddressList* addr,
57 const CompletionCallback& cb)
58 : info(req_info), addresses(addr), callback(cb) {}
59 RequestInfo info;
60 AddressList* addresses;
61 CompletionCallback callback;
64 MockHostResolverBase::~MockHostResolverBase() {
65 STLDeleteValues(&requests_);
68 int MockHostResolverBase::Resolve(const RequestInfo& info,
69 AddressList* addresses,
70 const CompletionCallback& callback,
71 RequestHandle* handle,
72 const BoundNetLog& net_log) {
73 DCHECK(CalledOnValidThread());
74 size_t id = next_request_id_++;
75 int rv = ResolveFromIPLiteralOrCache(info, addresses);
76 if (rv != ERR_DNS_CACHE_MISS) {
77 return rv;
79 if (synchronous_mode_) {
80 return ResolveProc(id, info, addresses);
82 // Store the request for asynchronous resolution
83 Request* req = new Request(info, addresses, callback);
84 requests_[id] = req;
85 if (handle)
86 *handle = reinterpret_cast<RequestHandle>(id);
88 if (!ondemand_mode_) {
89 MessageLoop::current()->PostTask(
90 FROM_HERE,
91 base::Bind(&MockHostResolverBase::ResolveNow, AsWeakPtr(), id));
94 return ERR_IO_PENDING;
97 int MockHostResolverBase::ResolveFromCache(const RequestInfo& info,
98 AddressList* addresses,
99 const BoundNetLog& net_log) {
100 DCHECK(CalledOnValidThread());
101 next_request_id_++;
102 int rv = ResolveFromIPLiteralOrCache(info, addresses);
103 return rv;
106 void MockHostResolverBase::CancelRequest(RequestHandle handle) {
107 DCHECK(CalledOnValidThread());
108 size_t id = reinterpret_cast<size_t>(handle);
109 RequestMap::iterator it = requests_.find(id);
110 if (it != requests_.end()) {
111 scoped_ptr<Request> req(it->second);
112 requests_.erase(it);
113 } else {
114 NOTREACHED() << "CancelRequest must NOT be called after request is "
115 "complete or canceled.";
119 HostCache* MockHostResolverBase::GetHostCache() {
120 return cache_.get();
123 void MockHostResolverBase::ResolveAllPending() {
124 DCHECK(CalledOnValidThread());
125 DCHECK(ondemand_mode_);
126 for (RequestMap::iterator i = requests_.begin(); i != requests_.end(); ++i) {
127 MessageLoop::current()->PostTask(
128 FROM_HERE,
129 base::Bind(&MockHostResolverBase::ResolveNow, AsWeakPtr(), i->first));
133 // start id from 1 to distinguish from NULL RequestHandle
134 MockHostResolverBase::MockHostResolverBase(bool use_caching)
135 : synchronous_mode_(false),
136 ondemand_mode_(false),
137 next_request_id_(1) {
138 rules_ = CreateCatchAllHostResolverProc();
140 if (use_caching) {
141 cache_.reset(new HostCache(kMaxCacheEntries));
145 int MockHostResolverBase::ResolveFromIPLiteralOrCache(const RequestInfo& info,
146 AddressList* addresses) {
147 IPAddressNumber ip;
148 if (ParseIPLiteralToNumber(info.hostname(), &ip)) {
149 *addresses = AddressList::CreateFromIPAddress(ip, info.port());
150 if (info.host_resolver_flags() & HOST_RESOLVER_CANONNAME)
151 addresses->SetDefaultCanonicalName();
152 return OK;
154 int rv = ERR_DNS_CACHE_MISS;
155 if (cache_.get() && info.allow_cached_response()) {
156 HostCache::Key key(info.hostname(),
157 info.address_family(),
158 info.host_resolver_flags());
159 const HostCache::Entry* entry = cache_->Lookup(key, base::TimeTicks::Now());
160 if (entry) {
161 rv = entry->error;
162 if (rv == OK)
163 *addresses = AddressList::CopyWithPort(entry->addrlist, info.port());
166 return rv;
169 int MockHostResolverBase::ResolveProc(size_t id,
170 const RequestInfo& info,
171 AddressList* addresses) {
172 AddressList addr;
173 int rv = rules_->Resolve(info.hostname(),
174 info.address_family(),
175 info.host_resolver_flags(),
176 &addr,
177 NULL);
178 if (cache_.get()) {
179 HostCache::Key key(info.hostname(),
180 info.address_family(),
181 info.host_resolver_flags());
182 // Storing a failure with TTL 0 so that it overwrites previous value.
183 base::TimeDelta ttl;
184 if (rv == OK)
185 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds);
186 cache_->Set(key, HostCache::Entry(rv, addr), base::TimeTicks::Now(), ttl);
188 if (rv == OK)
189 *addresses = AddressList::CopyWithPort(addr, info.port());
190 return rv;
193 void MockHostResolverBase::ResolveNow(size_t id) {
194 RequestMap::iterator it = requests_.find(id);
195 if (it == requests_.end())
196 return; // was canceled
198 scoped_ptr<Request> req(it->second);
199 requests_.erase(it);
200 int rv = ResolveProc(id, req->info, req->addresses);
201 if (!req->callback.is_null())
202 req->callback.Run(rv);
205 //-----------------------------------------------------------------------------
207 struct RuleBasedHostResolverProc::Rule {
208 enum ResolverType {
209 kResolverTypeFail,
210 kResolverTypeSystem,
211 kResolverTypeIPLiteral,
214 ResolverType resolver_type;
215 std::string host_pattern;
216 AddressFamily address_family;
217 HostResolverFlags host_resolver_flags;
218 std::string replacement;
219 std::string canonical_name;
220 int latency_ms; // In milliseconds.
222 Rule(ResolverType resolver_type,
223 const std::string& host_pattern,
224 AddressFamily address_family,
225 HostResolverFlags host_resolver_flags,
226 const std::string& replacement,
227 const std::string& canonical_name,
228 int latency_ms)
229 : resolver_type(resolver_type),
230 host_pattern(host_pattern),
231 address_family(address_family),
232 host_resolver_flags(host_resolver_flags),
233 replacement(replacement),
234 canonical_name(canonical_name),
235 latency_ms(latency_ms) {}
238 RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous)
239 : HostResolverProc(previous) {
242 void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern,
243 const std::string& replacement) {
244 AddRuleForAddressFamily(host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
245 replacement);
248 void RuleBasedHostResolverProc::AddRuleForAddressFamily(
249 const std::string& host_pattern,
250 AddressFamily address_family,
251 const std::string& replacement) {
252 DCHECK(!replacement.empty());
253 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
254 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
255 Rule rule(Rule::kResolverTypeSystem, host_pattern, address_family, flags,
256 replacement, "", 0);
257 rules_.push_back(rule);
260 void RuleBasedHostResolverProc::AddIPLiteralRule(
261 const std::string& host_pattern,
262 const std::string& ip_literal,
263 const std::string& canonical_name) {
264 // Literals are always resolved to themselves by HostResolverImpl,
265 // consequently we do not support remapping them.
266 IPAddressNumber ip_number;
267 DCHECK(!ParseIPLiteralToNumber(host_pattern, &ip_number));
268 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
269 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
270 if (!canonical_name.empty())
271 flags |= HOST_RESOLVER_CANONNAME;
272 Rule rule(Rule::kResolverTypeIPLiteral, host_pattern,
273 ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal, canonical_name,
275 rules_.push_back(rule);
278 void RuleBasedHostResolverProc::AddRuleWithLatency(
279 const std::string& host_pattern,
280 const std::string& replacement,
281 int latency_ms) {
282 DCHECK(!replacement.empty());
283 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
284 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
285 Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
286 flags, replacement, "", latency_ms);
287 rules_.push_back(rule);
290 void RuleBasedHostResolverProc::AllowDirectLookup(
291 const std::string& host_pattern) {
292 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
293 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
294 Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
295 flags, "", "", 0);
296 rules_.push_back(rule);
299 void RuleBasedHostResolverProc::AddSimulatedFailure(
300 const std::string& host_pattern) {
301 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
302 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
303 Rule rule(Rule::kResolverTypeFail, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
304 flags, "", "", 0);
305 rules_.push_back(rule);
308 int RuleBasedHostResolverProc::Resolve(const std::string& host,
309 AddressFamily address_family,
310 HostResolverFlags host_resolver_flags,
311 AddressList* addrlist,
312 int* os_error) {
313 RuleList::iterator r;
314 for (r = rules_.begin(); r != rules_.end(); ++r) {
315 bool matches_address_family =
316 r->address_family == ADDRESS_FAMILY_UNSPECIFIED ||
317 r->address_family == address_family;
318 // Flags match if all of the bitflags in host_resolver_flags are enabled
319 // in the rule's host_resolver_flags. However, the rule may have additional
320 // flags specified, in which case the flags should still be considered a
321 // match.
322 bool matches_flags = (r->host_resolver_flags & host_resolver_flags) ==
323 host_resolver_flags;
324 if (matches_flags && matches_address_family &&
325 MatchPattern(host, r->host_pattern)) {
326 if (r->latency_ms != 0) {
327 base::PlatformThread::Sleep(
328 base::TimeDelta::FromMilliseconds(r->latency_ms));
331 // Remap to a new host.
332 const std::string& effective_host =
333 r->replacement.empty() ? host : r->replacement;
335 // Apply the resolving function to the remapped hostname.
336 switch (r->resolver_type) {
337 case Rule::kResolverTypeFail:
338 return ERR_NAME_NOT_RESOLVED;
339 case Rule::kResolverTypeSystem:
340 #if defined(OS_WIN)
341 net::EnsureWinsockInit();
342 #endif
343 return SystemHostResolverProc(effective_host,
344 address_family,
345 host_resolver_flags,
346 addrlist, os_error);
347 case Rule::kResolverTypeIPLiteral:
348 return ParseAddressList(effective_host,
349 r->canonical_name,
350 addrlist);
351 default:
352 NOTREACHED();
353 return ERR_UNEXPECTED;
357 return ResolveUsingPrevious(host, address_family,
358 host_resolver_flags, addrlist, os_error);
361 RuleBasedHostResolverProc::~RuleBasedHostResolverProc() {
364 RuleBasedHostResolverProc* CreateCatchAllHostResolverProc() {
365 RuleBasedHostResolverProc* catchall = new RuleBasedHostResolverProc(NULL);
366 catchall->AddIPLiteralRule("*", "127.0.0.1", "localhost");
368 // Next add a rules-based layer the use controls.
369 return new RuleBasedHostResolverProc(catchall);
372 //-----------------------------------------------------------------------------
374 int HangingHostResolver::Resolve(const RequestInfo& info,
375 AddressList* addresses,
376 const CompletionCallback& callback,
377 RequestHandle* out_req,
378 const BoundNetLog& net_log) {
379 return ERR_IO_PENDING;
382 int HangingHostResolver::ResolveFromCache(const RequestInfo& info,
383 AddressList* addresses,
384 const BoundNetLog& net_log) {
385 return ERR_DNS_CACHE_MISS;
388 //-----------------------------------------------------------------------------
390 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc() {}
392 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc(
393 HostResolverProc* proc) {
394 Init(proc);
397 ScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() {
398 HostResolverProc* old_proc = HostResolverProc::SetDefault(previous_proc_);
399 // The lifetimes of multiple instances must be nested.
400 CHECK_EQ(old_proc, current_proc_);
403 void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) {
404 current_proc_ = proc;
405 previous_proc_ = HostResolverProc::SetDefault(current_proc_);
406 current_proc_->SetLastProc(previous_proc_);
409 } // namespace net