summaryrefslogtreecommitdiffstats
path: root/net/base
diff options
context:
space:
mode:
authorjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-14 22:40:42 +0000
committerjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-14 22:40:42 +0000
commit7af985a498165e9ba74d7e428be4ffe9a054f053 (patch)
tree88a20282a57a9b0bffc1d99f34e0ba7ae65f4063 /net/base
parentab108f2658ea9da9572085ea8bd501505f3f38c5 (diff)
downloadchromium_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.cc17
-rw-r--r--net/base/dnsrr_resolver_unittest.cc2
-rw-r--r--net/base/host_resolver_impl.cc8
-rw-r--r--net/base/host_resolver_impl.h4
-rw-r--r--net/base/host_resolver_impl_unittest.cc14
-rw-r--r--net/base/mock_host_resolver.cc25
-rw-r--r--net/base/mock_host_resolver.h18
-rw-r--r--net/base/net_error_list.h3
-rw-r--r--net/base/network_change_notifier.h1
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;