| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/host_resolver_impl.h" | 5 #include "net/base/host_resolver_impl.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <ws2tcpip.h> | 8 #include <ws2tcpip.h> |
| 9 #include <wspiapi.h> // Needed for Win2k compat. | 9 #include <wspiapi.h> // Needed for Win2k compat. |
| 10 #elif defined(OS_POSIX) | 10 #elif defined(OS_POSIX) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
| 29 | 29 |
| 30 #if defined(OS_WIN) | 30 #if defined(OS_WIN) |
| 31 #include "net/base/winsock_init.h" | 31 #include "net/base/winsock_init.h" |
| 32 #endif | 32 #endif |
| 33 | 33 |
| 34 namespace net { | 34 namespace net { |
| 35 | 35 |
| 36 HostResolver* CreateSystemHostResolver() { | 36 HostResolver* CreateSystemHostResolver() { |
| 37 static const size_t kMaxHostCacheEntries = 100; | 37 static const size_t kMaxHostCacheEntries = 100; |
| 38 static const size_t kHostCacheExpirationMs = 60000; // 1 minute. | 38 |
| 39 return new HostResolverImpl( | 39 HostCache* cache = new HostCache( |
| 40 NULL, kMaxHostCacheEntries, kHostCacheExpirationMs); | 40 kMaxHostCacheEntries, |
| 41 base::TimeDelta::FromMinutes(1), |
| 42 base::TimeDelta::FromSeconds(1)); |
| 43 |
| 44 return new HostResolverImpl(NULL, cache); |
| 41 } | 45 } |
| 42 | 46 |
| 43 static int ResolveAddrInfo(HostResolverProc* resolver_proc, | 47 static int ResolveAddrInfo(HostResolverProc* resolver_proc, |
| 44 const std::string& host, | 48 const std::string& host, |
| 45 AddressFamily address_family, | 49 AddressFamily address_family, |
| 46 AddressList* out) { | 50 AddressList* out) { |
| 47 if (resolver_proc) { | 51 if (resolver_proc) { |
| 48 // Use the custom procedure. | 52 // Use the custom procedure. |
| 49 return resolver_proc->Resolve(host, address_family, out); | 53 return resolver_proc->Resolve(host, address_family, out); |
| 50 } else { | 54 } else { |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 // Assigned on the worker thread, read on the origin thread. | 284 // Assigned on the worker thread, read on the origin thread. |
| 281 int error_; | 285 int error_; |
| 282 AddressList results_; | 286 AddressList results_; |
| 283 | 287 |
| 284 DISALLOW_COPY_AND_ASSIGN(Job); | 288 DISALLOW_COPY_AND_ASSIGN(Job); |
| 285 }; | 289 }; |
| 286 | 290 |
| 287 //----------------------------------------------------------------------------- | 291 //----------------------------------------------------------------------------- |
| 288 | 292 |
| 289 HostResolverImpl::HostResolverImpl(HostResolverProc* resolver_proc, | 293 HostResolverImpl::HostResolverImpl(HostResolverProc* resolver_proc, |
| 290 int max_cache_entries, | 294 HostCache* cache) |
| 291 int cache_duration_ms) | 295 : cache_(cache), |
| 292 : cache_(max_cache_entries, cache_duration_ms), | |
| 293 next_request_id_(0), | 296 next_request_id_(0), |
| 294 resolver_proc_(resolver_proc), | 297 resolver_proc_(resolver_proc), |
| 295 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), | 298 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), |
| 296 shutdown_(false) { | 299 shutdown_(false) { |
| 297 #if defined(OS_WIN) | 300 #if defined(OS_WIN) |
| 298 EnsureWinsockInit(); | 301 EnsureWinsockInit(); |
| 299 #endif | 302 #endif |
| 300 } | 303 } |
| 301 | 304 |
| 302 HostResolverImpl::~HostResolverImpl() { | 305 HostResolverImpl::~HostResolverImpl() { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 326 // Update the load log and notify registered observers. | 329 // Update the load log and notify registered observers. |
| 327 OnStartRequest(load_log, request_id, info); | 330 OnStartRequest(load_log, request_id, info); |
| 328 | 331 |
| 329 // Build a key that identifies the request in the cache and in the | 332 // Build a key that identifies the request in the cache and in the |
| 330 // outstanding jobs map. | 333 // outstanding jobs map. |
| 331 Key key(info.hostname(), info.address_family()); | 334 Key key(info.hostname(), info.address_family()); |
| 332 if (key.address_family == ADDRESS_FAMILY_UNSPECIFIED) | 335 if (key.address_family == ADDRESS_FAMILY_UNSPECIFIED) |
| 333 key.address_family = default_address_family_; | 336 key.address_family = default_address_family_; |
| 334 | 337 |
| 335 // If we have an unexpired cache entry, use it. | 338 // If we have an unexpired cache entry, use it. |
| 336 if (info.allow_cached_response()) { | 339 if (info.allow_cached_response() && cache_.get()) { |
| 337 const HostCache::Entry* cache_entry = cache_.Lookup( | 340 const HostCache::Entry* cache_entry = cache_->Lookup( |
| 338 key, base::TimeTicks::Now()); | 341 key, base::TimeTicks::Now()); |
| 339 if (cache_entry) { | 342 if (cache_entry) { |
| 340 addresses->SetFrom(cache_entry->addrlist, info.port()); | |
| 341 int error = cache_entry->error; | 343 int error = cache_entry->error; |
| 344 if (error == OK) |
| 345 addresses->SetFrom(cache_entry->addrlist, info.port()); |
| 342 | 346 |
| 343 // Update the load log and notify registered observers. | 347 // Update the load log and notify registered observers. |
| 344 OnFinishRequest(load_log, request_id, info, error); | 348 OnFinishRequest(load_log, request_id, info, error); |
| 345 | 349 |
| 346 return error; | 350 return error; |
| 347 } | 351 } |
| 348 } | 352 } |
| 349 | 353 |
| 350 // If no callback was specified, do a synchronous resolution. | 354 // If no callback was specified, do a synchronous resolution. |
| 351 if (!callback) { | 355 if (!callback) { |
| 352 AddressList addrlist; | 356 AddressList addrlist; |
| 353 int error = ResolveAddrInfo( | 357 int error = ResolveAddrInfo( |
| 354 effective_resolver_proc(), key.hostname, key.address_family, &addrlist); | 358 effective_resolver_proc(), key.hostname, key.address_family, &addrlist); |
| 355 if (error == OK) { | 359 if (error == OK) { |
| 356 addrlist.SetPort(info.port()); | 360 addrlist.SetPort(info.port()); |
| 357 *addresses = addrlist; | 361 *addresses = addrlist; |
| 358 } | 362 } |
| 359 | 363 |
| 360 // Write to cache. | 364 // Write to cache. |
| 361 cache_.Set(key, error, addrlist, base::TimeTicks::Now()); | 365 if (cache_.get()) |
| 366 cache_->Set(key, error, addrlist, base::TimeTicks::Now()); |
| 362 | 367 |
| 363 // Update the load log and notify registered observers. | 368 // Update the load log and notify registered observers. |
| 364 OnFinishRequest(load_log, request_id, info, error); | 369 OnFinishRequest(load_log, request_id, info, error); |
| 365 | 370 |
| 366 return error; | 371 return error; |
| 367 } | 372 } |
| 368 | 373 |
| 369 // Create a handle for this request, and pass it back to the user if they | 374 // Create a handle for this request, and pass it back to the user if they |
| 370 // asked for it (out_req != NULL). | 375 // asked for it (out_req != NULL). |
| 371 Request* req = new Request(load_log, request_id, info, callback, addresses); | 376 Request* req = new Request(load_log, request_id, info, callback, addresses); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 ObserversList::iterator it = | 427 ObserversList::iterator it = |
| 423 std::find(observers_.begin(), observers_.end(), observer); | 428 std::find(observers_.begin(), observers_.end(), observer); |
| 424 | 429 |
| 425 // Observer must exist. | 430 // Observer must exist. |
| 426 DCHECK(it != observers_.end()); | 431 DCHECK(it != observers_.end()); |
| 427 | 432 |
| 428 observers_.erase(it); | 433 observers_.erase(it); |
| 429 } | 434 } |
| 430 | 435 |
| 431 HostCache* HostResolverImpl::GetHostCache() { | 436 HostCache* HostResolverImpl::GetHostCache() { |
| 432 return &cache_; | 437 return cache_.get(); |
| 433 } | 438 } |
| 434 | 439 |
| 435 void HostResolverImpl::Shutdown() { | 440 void HostResolverImpl::Shutdown() { |
| 436 shutdown_ = true; | 441 shutdown_ = true; |
| 437 | 442 |
| 438 // Cancel the outstanding jobs. | 443 // Cancel the outstanding jobs. |
| 439 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it) | 444 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it) |
| 440 it->second->Cancel(); | 445 it->second->Cancel(); |
| 441 jobs_.clear(); | 446 jobs_.clear(); |
| 442 } | 447 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 460 DCHECK_EQ(it->second.get(), job); | 465 DCHECK_EQ(it->second.get(), job); |
| 461 jobs_.erase(it); | 466 jobs_.erase(it); |
| 462 } | 467 } |
| 463 | 468 |
| 464 void HostResolverImpl::OnJobComplete(Job* job, | 469 void HostResolverImpl::OnJobComplete(Job* job, |
| 465 int error, | 470 int error, |
| 466 const AddressList& addrlist) { | 471 const AddressList& addrlist) { |
| 467 RemoveOutstandingJob(job); | 472 RemoveOutstandingJob(job); |
| 468 | 473 |
| 469 // Write result to the cache. | 474 // Write result to the cache. |
| 470 cache_.Set(job->key(), error, addrlist, base::TimeTicks::Now()); | 475 if (cache_.get()) |
| 476 cache_->Set(job->key(), error, addrlist, base::TimeTicks::Now()); |
| 471 | 477 |
| 472 // Make a note that we are executing within OnJobComplete() in case the | 478 // Make a note that we are executing within OnJobComplete() in case the |
| 473 // HostResolver is deleted by a callback invocation. | 479 // HostResolver is deleted by a callback invocation. |
| 474 DCHECK(!cur_completing_job_); | 480 DCHECK(!cur_completing_job_); |
| 475 cur_completing_job_ = job; | 481 cur_completing_job_ = job; |
| 476 | 482 |
| 477 // Complete all of the requests that were attached to the job. | 483 // Complete all of the requests that were attached to the job. |
| 478 for (RequestsList::const_iterator it = job->requests().begin(); | 484 for (RequestsList::const_iterator it = job->requests().begin(); |
| 479 it != job->requests().end(); ++it) { | 485 it != job->requests().end(); ++it) { |
| 480 Request* req = *it; | 486 Request* req = *it; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 } | 560 } |
| 555 | 561 |
| 556 LoadLog::EndEvent( | 562 LoadLog::EndEvent( |
| 557 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONCANCEL); | 563 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONCANCEL); |
| 558 } | 564 } |
| 559 | 565 |
| 560 LoadLog::EndEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL); | 566 LoadLog::EndEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL); |
| 561 } | 567 } |
| 562 | 568 |
| 563 } // namespace net | 569 } // namespace net |
| OLD | NEW |