diff options
author | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-14 22:40:42 +0000 |
---|---|---|
committer | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-14 22:40:42 +0000 |
commit | 7af985a498165e9ba74d7e428be4ffe9a054f053 (patch) | |
tree | 88a20282a57a9b0bffc1d99f34e0ba7ae65f4063 /net/base | |
parent | ab108f2658ea9da9572085ea8bd501505f3f38c5 (diff) | |
download | chromium_src-7af985a498165e9ba74d7e428be4ffe9a054f053.zip chromium_src-7af985a498165e9ba74d7e428be4ffe9a054f053.tar.gz chromium_src-7af985a498165e9ba74d7e428be4ffe9a054f053.tar.bz2 |
Introduce ERR_NETWORK_CHANGED and allow URLFetcher to automatically retry on that error.
BUG=164363
Review URL: https://codereview.chromium.org/11464028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173227 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/dnsrr_resolver.cc | 17 | ||||
-rw-r--r-- | net/base/dnsrr_resolver_unittest.cc | 2 | ||||
-rw-r--r-- | net/base/host_resolver_impl.cc | 8 | ||||
-rw-r--r-- | net/base/host_resolver_impl.h | 4 | ||||
-rw-r--r-- | net/base/host_resolver_impl_unittest.cc | 14 | ||||
-rw-r--r-- | net/base/mock_host_resolver.cc | 25 | ||||
-rw-r--r-- | net/base/mock_host_resolver.h | 18 | ||||
-rw-r--r-- | net/base/net_error_list.h | 3 | ||||
-rw-r--r-- | net/base/network_change_notifier.h | 1 |
9 files changed, 68 insertions, 24 deletions
diff --git a/net/base/dnsrr_resolver.cc b/net/base/dnsrr_resolver.cc index cfe63e2..3fecfe3 100644 --- a/net/base/dnsrr_resolver.cc +++ b/net/base/dnsrr_resolver.cc @@ -509,11 +509,7 @@ class RRResolverJob { } ~RRResolverJob() { - if (worker_) { - worker_->Cancel(); - worker_ = NULL; - PostAll(ERR_ABORTED, NULL); - } + Cancel(ERR_ABORTED); } void AddHandle(RRResolverHandle* handle) { @@ -525,6 +521,14 @@ class RRResolverJob { PostAll(result, &response); } + void Cancel(int result) { + if (worker_) { + worker_->Cancel(); + worker_ = NULL; + PostAll(result, NULL); + } + } + private: void PostAll(int result, const RRResponse* response) { std::vector<RRResolverHandle*> handles; @@ -643,6 +647,9 @@ void DnsRRResolver::OnIPAddressChanged() { inflight.swap(inflight_); cache_.clear(); + std::map<std::pair<std::string, uint16>, RRResolverJob*>::iterator it; + for (it = inflight.begin(); it != inflight.end(); ++it) + it->second->Cancel(ERR_NETWORK_CHANGED); STLDeleteValues(&inflight); } diff --git a/net/base/dnsrr_resolver_unittest.cc b/net/base/dnsrr_resolver_unittest.cc index cc6e80b..0b67b65 100644 --- a/net/base/dnsrr_resolver_unittest.cc +++ b/net/base/dnsrr_resolver_unittest.cc @@ -97,7 +97,7 @@ TEST(DnsRRResolverTest, Resolve) { ASSERT_TRUE(handle != DnsRRResolver::kInvalidHandle); resolver.OnIPAddressChanged(); ASSERT_TRUE(callback.have_result()); - ASSERT_EQ(ERR_ABORTED, callback.WaitForResult()); + ASSERT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult()); ASSERT_EQ(4u, resolver.requests()); ASSERT_EQ(2u, resolver.cache_hits()); ASSERT_EQ(0u, resolver.inflight_joins()); diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc index 64c9d2a..4b6bb3ad 100644 --- a/net/base/host_resolver_impl.cc +++ b/net/base/host_resolver_impl.cc @@ -1267,11 +1267,11 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job { } } - // Called from AbortAllInProgressJobs. Completes all requests as aborted - // and destroys the job. + // Called from AbortAllInProgressJobs. Completes all requests and destroys + // the job. This currently assumes the abort is due to a network change. void Abort() { DCHECK(is_running()); - CompleteRequestsWithError(ERR_ABORTED); + CompleteRequestsWithError(ERR_NETWORK_CHANGED); } // If DnsTask present, abort it and fall back to ProcTask. @@ -1531,7 +1531,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job { resolver_->received_dns_config_); } - bool did_complete = (entry.error != ERR_ABORTED) && + bool did_complete = (entry.error != ERR_NETWORK_CHANGED) && (entry.error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE); if (did_complete) resolver_->CacheResult(key_, entry, ttl); diff --git a/net/base/host_resolver_impl.h b/net/base/host_resolver_impl.h index 61096641..d68d6ab 100644 --- a/net/base/host_resolver_impl.h +++ b/net/base/host_resolver_impl.h @@ -207,8 +207,8 @@ class NET_EXPORT HostResolverImpl // Removes |job| from |jobs_|, only if it exists. void RemoveJob(Job* job); - // Aborts all in progress jobs and notifies their requests. - // Might start new jobs. + // Aborts all in progress jobs with ERR_NETWORK_CHANGED and notifies their + // requests. Might start new jobs. void AbortAllInProgressJobs(); // Attempts to serve each Job in |jobs_| from the HOSTS file if we have diff --git a/net/base/host_resolver_impl_unittest.cc b/net/base/host_resolver_impl_unittest.cc index 08262a5..bc6b870 100644 --- a/net/base/host_resolver_impl_unittest.cc +++ b/net/base/host_resolver_impl_unittest.cc @@ -735,7 +735,7 @@ TEST_F(HostResolverImplTest, DeleteWithinAbortedCallback) { // |MyHandler| will send quit message once all the requests have finished. MessageLoop::current()->Run(); - EXPECT_EQ(ERR_ABORTED, requests_[0]->result()); + EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[0]->result()); EXPECT_EQ(ERR_IO_PENDING, requests_[1]->result()); EXPECT_EQ(ERR_IO_PENDING, requests_[2]->result()); EXPECT_EQ(ERR_IO_PENDING, requests_[3]->result()); @@ -830,7 +830,7 @@ TEST_F(HostResolverImplTest, FlushCacheOnIPAddressChange) { EXPECT_EQ(OK, req->WaitForResult()); } -// Test that IP address changes send ERR_ABORTED to pending requests. +// Test that IP address changes send ERR_NETWORK_CHANGED to pending requests. TEST_F(HostResolverImplTest, AbortOnIPAddressChanged) { Request* req = CreateRequest("host1", 70); EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); @@ -841,7 +841,7 @@ TEST_F(HostResolverImplTest, AbortOnIPAddressChanged) { MessageLoop::current()->RunUntilIdle(); // Notification happens async. proc_->SignalAll(); - EXPECT_EQ(ERR_ABORTED, req->WaitForResult()); + EXPECT_EQ(ERR_NETWORK_CHANGED, req->WaitForResult()); EXPECT_EQ(0u, resolver_->GetHostCache()->size()); } @@ -859,7 +859,7 @@ TEST_F(HostResolverImplTest, ObeyPoolConstraintsAfterIPAddressChange) { MessageLoop::current()->RunUntilIdle(); // Notification happens async. proc_->SignalMultiple(3u); // Let the false-start go so that we can catch it. - EXPECT_EQ(ERR_ABORTED, requests_[0]->WaitForResult()); + EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[0]->WaitForResult()); EXPECT_EQ(1u, num_running_jobs()); @@ -901,9 +901,9 @@ TEST_F(HostResolverImplTest, AbortOnlyExistingRequestsOnIPAddressChange) { NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); // This should abort all running jobs. MessageLoop::current()->RunUntilIdle(); - EXPECT_EQ(ERR_ABORTED, requests_[0]->result()); - EXPECT_EQ(ERR_ABORTED, requests_[1]->result()); - EXPECT_EQ(ERR_ABORTED, requests_[2]->result()); + EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[0]->result()); + EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[1]->result()); + EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[2]->result()); ASSERT_EQ(6u, requests_.size()); // Unblock all calls to proc. proc_->SignalMultiple(requests_.size()); diff --git a/net/base/mock_host_resolver.cc b/net/base/mock_host_resolver.cc index d86e209..a0835b8 100644 --- a/net/base/mock_host_resolver.cc +++ b/net/base/mock_host_resolver.cc @@ -84,10 +84,13 @@ int MockHostResolverBase::Resolve(const RequestInfo& info, requests_[id] = req; if (handle) *handle = reinterpret_cast<RequestHandle>(id); - MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(&MockHostResolverBase::ResolveNow, - AsWeakPtr(), - id)); + + if (!ondemand_mode_) { + MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&MockHostResolverBase::ResolveNow, AsWeakPtr(), id)); + } + return ERR_IO_PENDING; } @@ -117,9 +120,21 @@ HostCache* MockHostResolverBase::GetHostCache() { return cache_.get(); } +void MockHostResolverBase::ResolveAllPending() { + DCHECK(CalledOnValidThread()); + DCHECK(ondemand_mode_); + for (RequestMap::iterator i = requests_.begin(); i != requests_.end(); ++i) { + MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&MockHostResolverBase::ResolveNow, AsWeakPtr(), i->first)); + } +} + // start id from 1 to distinguish from NULL RequestHandle MockHostResolverBase::MockHostResolverBase(bool use_caching) - : synchronous_mode_(false), next_request_id_(1) { + : synchronous_mode_(false), + ondemand_mode_(false), + next_request_id_(1) { rules_ = CreateCatchAllHostResolverProc(); if (use_caching) { diff --git a/net/base/mock_host_resolver.h b/net/base/mock_host_resolver.h index 033cf14..5542a64 100644 --- a/net/base/mock_host_resolver.h +++ b/net/base/mock_host_resolver.h @@ -65,6 +65,14 @@ class MockHostResolverBase : public HostResolver, synchronous_mode_ = is_synchronous; } + // Asynchronous requests are automatically resolved by default. + // If set_ondemand_mode() is set then Resolve() returns IO_PENDING and + // ResolveAllPending() must be explicitly invoked to resolve all requests + // that are pending. + void set_ondemand_mode(bool is_ondemand) { + ondemand_mode_ = is_ondemand; + } + // HostResolver methods: virtual int Resolve(const RequestInfo& info, AddressList* addresses, @@ -77,6 +85,15 @@ class MockHostResolverBase : public HostResolver, virtual void CancelRequest(RequestHandle req) OVERRIDE; virtual HostCache* GetHostCache() OVERRIDE; + // Resolves all pending requests. It is only valid to invoke this if + // set_ondemand_mode was set before. The requests are resolved asynchronously, + // after this call returns. + void ResolveAllPending(); + + // Returns true if there are pending requests that can be resolved by invoking + // ResolveAllPending(). + bool has_pending_requests() const { return !requests_.empty(); } + protected: explicit MockHostResolverBase(bool use_caching); @@ -94,6 +111,7 @@ class MockHostResolverBase : public HostResolver, void ResolveNow(size_t id); bool synchronous_mode_; + bool ondemand_mode_; scoped_refptr<RuleBasedHostResolverProc> rules_; scoped_ptr<HostCache> cache_; RequestMap requests_; diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index fe98e42..44f0c8d 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h @@ -84,6 +84,9 @@ NET_ERROR(FILE_VIRUS_INFECTED, -19) // The client chose to block the request. NET_ERROR(BLOCKED_BY_CLIENT, -20) +// The network changed. +NET_ERROR(NETWORK_CHANGED, -21) + // A connection was closed (corresponding to a TCP FIN). NET_ERROR(CONNECTION_CLOSED, -100) diff --git a/net/base/network_change_notifier.h b/net/base/network_change_notifier.h index fe8d091..124e084 100644 --- a/net/base/network_change_notifier.h +++ b/net/base/network_change_notifier.h @@ -274,6 +274,7 @@ class NET_EXPORT NetworkChangeNotifier { friend class NetworkChangeNotifierAndroidTest; friend class NetworkChangeNotifierLinuxTest; friend class NetworkChangeNotifierWinTest; + friend class URLFetcherMockDnsTest; class NetworkState; class NetworkChangeCalculator; |