move SK_DISABLE_DITHER_32BIT_GRADIENT from SkUserConfig.h to skia.gyp, so we can...
[chromium-blink-merge.git] / net / base / mock_host_resolver.cc
blobd86e20924c538c1bb1ce40c16840b07e9c4dcef4
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);
87 MessageLoop::current()->PostTask(FROM_HERE,
88 base::Bind(&MockHostResolverBase::ResolveNow,
89 AsWeakPtr(),
90 id));
91 return ERR_IO_PENDING;
94 int MockHostResolverBase::ResolveFromCache(const RequestInfo& info,
95 AddressList* addresses,
96 const BoundNetLog& net_log) {
97 DCHECK(CalledOnValidThread());
98 next_request_id_++;
99 int rv = ResolveFromIPLiteralOrCache(info, addresses);
100 return rv;
103 void MockHostResolverBase::CancelRequest(RequestHandle handle) {
104 DCHECK(CalledOnValidThread());
105 size_t id = reinterpret_cast<size_t>(handle);
106 RequestMap::iterator it = requests_.find(id);
107 if (it != requests_.end()) {
108 scoped_ptr<Request> req(it->second);
109 requests_.erase(it);
110 } else {
111 NOTREACHED() << "CancelRequest must NOT be called after request is "
112 "complete or canceled.";
116 HostCache* MockHostResolverBase::GetHostCache() {
117 return cache_.get();
120 // start id from 1 to distinguish from NULL RequestHandle
121 MockHostResolverBase::MockHostResolverBase(bool use_caching)
122 : synchronous_mode_(false), next_request_id_(1) {
123 rules_ = CreateCatchAllHostResolverProc();
125 if (use_caching) {
126 cache_.reset(new HostCache(kMaxCacheEntries));
130 int MockHostResolverBase::ResolveFromIPLiteralOrCache(const RequestInfo& info,
131 AddressList* addresses) {
132 IPAddressNumber ip;
133 if (ParseIPLiteralToNumber(info.hostname(), &ip)) {
134 *addresses = AddressList::CreateFromIPAddress(ip, info.port());
135 if (info.host_resolver_flags() & HOST_RESOLVER_CANONNAME)
136 addresses->SetDefaultCanonicalName();
137 return OK;
139 int rv = ERR_DNS_CACHE_MISS;
140 if (cache_.get() && info.allow_cached_response()) {
141 HostCache::Key key(info.hostname(),
142 info.address_family(),
143 info.host_resolver_flags());
144 const HostCache::Entry* entry = cache_->Lookup(key, base::TimeTicks::Now());
145 if (entry) {
146 rv = entry->error;
147 if (rv == OK)
148 *addresses = AddressList::CopyWithPort(entry->addrlist, info.port());
151 return rv;
154 int MockHostResolverBase::ResolveProc(size_t id,
155 const RequestInfo& info,
156 AddressList* addresses) {
157 AddressList addr;
158 int rv = rules_->Resolve(info.hostname(),
159 info.address_family(),
160 info.host_resolver_flags(),
161 &addr,
162 NULL);
163 if (cache_.get()) {
164 HostCache::Key key(info.hostname(),
165 info.address_family(),
166 info.host_resolver_flags());
167 // Storing a failure with TTL 0 so that it overwrites previous value.
168 base::TimeDelta ttl;
169 if (rv == OK)
170 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds);
171 cache_->Set(key, HostCache::Entry(rv, addr), base::TimeTicks::Now(), ttl);
173 if (rv == OK)
174 *addresses = AddressList::CopyWithPort(addr, info.port());
175 return rv;
178 void MockHostResolverBase::ResolveNow(size_t id) {
179 RequestMap::iterator it = requests_.find(id);
180 if (it == requests_.end())
181 return; // was canceled
183 scoped_ptr<Request> req(it->second);
184 requests_.erase(it);
185 int rv = ResolveProc(id, req->info, req->addresses);
186 if (!req->callback.is_null())
187 req->callback.Run(rv);
190 //-----------------------------------------------------------------------------
192 struct RuleBasedHostResolverProc::Rule {
193 enum ResolverType {
194 kResolverTypeFail,
195 kResolverTypeSystem,
196 kResolverTypeIPLiteral,
199 ResolverType resolver_type;
200 std::string host_pattern;
201 AddressFamily address_family;
202 HostResolverFlags host_resolver_flags;
203 std::string replacement;
204 std::string canonical_name;
205 int latency_ms; // In milliseconds.
207 Rule(ResolverType resolver_type,
208 const std::string& host_pattern,
209 AddressFamily address_family,
210 HostResolverFlags host_resolver_flags,
211 const std::string& replacement,
212 const std::string& canonical_name,
213 int latency_ms)
214 : resolver_type(resolver_type),
215 host_pattern(host_pattern),
216 address_family(address_family),
217 host_resolver_flags(host_resolver_flags),
218 replacement(replacement),
219 canonical_name(canonical_name),
220 latency_ms(latency_ms) {}
223 RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous)
224 : HostResolverProc(previous) {
227 void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern,
228 const std::string& replacement) {
229 AddRuleForAddressFamily(host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
230 replacement);
233 void RuleBasedHostResolverProc::AddRuleForAddressFamily(
234 const std::string& host_pattern,
235 AddressFamily address_family,
236 const std::string& replacement) {
237 DCHECK(!replacement.empty());
238 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
239 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
240 Rule rule(Rule::kResolverTypeSystem, host_pattern, address_family, flags,
241 replacement, "", 0);
242 rules_.push_back(rule);
245 void RuleBasedHostResolverProc::AddIPLiteralRule(
246 const std::string& host_pattern,
247 const std::string& ip_literal,
248 const std::string& canonical_name) {
249 // Literals are always resolved to themselves by HostResolverImpl,
250 // consequently we do not support remapping them.
251 IPAddressNumber ip_number;
252 DCHECK(!ParseIPLiteralToNumber(host_pattern, &ip_number));
253 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
254 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
255 if (!canonical_name.empty())
256 flags |= HOST_RESOLVER_CANONNAME;
257 Rule rule(Rule::kResolverTypeIPLiteral, host_pattern,
258 ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal, canonical_name,
260 rules_.push_back(rule);
263 void RuleBasedHostResolverProc::AddRuleWithLatency(
264 const std::string& host_pattern,
265 const std::string& replacement,
266 int latency_ms) {
267 DCHECK(!replacement.empty());
268 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
269 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
270 Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
271 flags, replacement, "", latency_ms);
272 rules_.push_back(rule);
275 void RuleBasedHostResolverProc::AllowDirectLookup(
276 const std::string& host_pattern) {
277 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
278 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
279 Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
280 flags, "", "", 0);
281 rules_.push_back(rule);
284 void RuleBasedHostResolverProc::AddSimulatedFailure(
285 const std::string& host_pattern) {
286 HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
287 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
288 Rule rule(Rule::kResolverTypeFail, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
289 flags, "", "", 0);
290 rules_.push_back(rule);
293 int RuleBasedHostResolverProc::Resolve(const std::string& host,
294 AddressFamily address_family,
295 HostResolverFlags host_resolver_flags,
296 AddressList* addrlist,
297 int* os_error) {
298 RuleList::iterator r;
299 for (r = rules_.begin(); r != rules_.end(); ++r) {
300 bool matches_address_family =
301 r->address_family == ADDRESS_FAMILY_UNSPECIFIED ||
302 r->address_family == address_family;
303 // Flags match if all of the bitflags in host_resolver_flags are enabled
304 // in the rule's host_resolver_flags. However, the rule may have additional
305 // flags specified, in which case the flags should still be considered a
306 // match.
307 bool matches_flags = (r->host_resolver_flags & host_resolver_flags) ==
308 host_resolver_flags;
309 if (matches_flags && matches_address_family &&
310 MatchPattern(host, r->host_pattern)) {
311 if (r->latency_ms != 0) {
312 base::PlatformThread::Sleep(
313 base::TimeDelta::FromMilliseconds(r->latency_ms));
316 // Remap to a new host.
317 const std::string& effective_host =
318 r->replacement.empty() ? host : r->replacement;
320 // Apply the resolving function to the remapped hostname.
321 switch (r->resolver_type) {
322 case Rule::kResolverTypeFail:
323 return ERR_NAME_NOT_RESOLVED;
324 case Rule::kResolverTypeSystem:
325 #if defined(OS_WIN)
326 net::EnsureWinsockInit();
327 #endif
328 return SystemHostResolverProc(effective_host,
329 address_family,
330 host_resolver_flags,
331 addrlist, os_error);
332 case Rule::kResolverTypeIPLiteral:
333 return ParseAddressList(effective_host,
334 r->canonical_name,
335 addrlist);
336 default:
337 NOTREACHED();
338 return ERR_UNEXPECTED;
342 return ResolveUsingPrevious(host, address_family,
343 host_resolver_flags, addrlist, os_error);
346 RuleBasedHostResolverProc::~RuleBasedHostResolverProc() {
349 RuleBasedHostResolverProc* CreateCatchAllHostResolverProc() {
350 RuleBasedHostResolverProc* catchall = new RuleBasedHostResolverProc(NULL);
351 catchall->AddIPLiteralRule("*", "127.0.0.1", "localhost");
353 // Next add a rules-based layer the use controls.
354 return new RuleBasedHostResolverProc(catchall);
357 //-----------------------------------------------------------------------------
359 int HangingHostResolver::Resolve(const RequestInfo& info,
360 AddressList* addresses,
361 const CompletionCallback& callback,
362 RequestHandle* out_req,
363 const BoundNetLog& net_log) {
364 return ERR_IO_PENDING;
367 int HangingHostResolver::ResolveFromCache(const RequestInfo& info,
368 AddressList* addresses,
369 const BoundNetLog& net_log) {
370 return ERR_DNS_CACHE_MISS;
373 //-----------------------------------------------------------------------------
375 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc() {}
377 ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc(
378 HostResolverProc* proc) {
379 Init(proc);
382 ScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() {
383 HostResolverProc* old_proc = HostResolverProc::SetDefault(previous_proc_);
384 // The lifetimes of multiple instances must be nested.
385 CHECK_EQ(old_proc, current_proc_);
388 void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) {
389 current_proc_ = proc;
390 previous_proc_ = HostResolverProc::SetDefault(current_proc_);
391 current_proc_->SetLastProc(previous_proc_);
394 } // namespace net