Fix for an "update in progress" DCHECK.
A DCHECK in SafeBrowsingService::UpdateStarted can potentially be
triggered if there is an error opening the database for reading,
or if there is no response from the server for a update request.
Both of these cases can cause our 'update_in_progress_' flag to
not be reset properly before the next update.
This CL adds:
- a timeout for update responses
- better handling for database errors
that properly resets the update state.
BUG=12835 (http://crbug.com/12835)
TEST=None.
Review URL: http://codereview.chromium.org/165008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22814 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/safe_browsing/protocol_manager.cc b/chrome/browser/safe_browsing/protocol_manager.cc
index a720bcc..c81e96a9 100644
--- a/chrome/browser/safe_browsing/protocol_manager.cc
+++ b/chrome/browser/safe_browsing/protocol_manager.cc
@@ -28,6 +28,9 @@
// Maximum time, in seconds, from start up before we must issue an update query.
static const int kSbTimerStartIntervalSec = 5 * 60;
+// The maximum time, in seconds, to wait for a response to an update request.
+static const int kSbMaxUpdateWaitSec = 10;
+
// Update URL for querying about the latest set of chunk updates.
static const char* const kSbUpdateUrl =
"http://safebrowsing.clients.google.com/safebrowsing/downloads?client=%s"
@@ -235,9 +238,19 @@
hash_requests_.erase(it);
} else {
// Update, chunk or key response.
- DCHECK(source == request_.get());
fetcher.reset(request_.release());
+ if (request_type_ == UPDATE_REQUEST) {
+ if (!fetcher.get()) {
+ // We've timed out waiting for an update response, so we've cancelled
+ // the update request and scheduled a new one. Ignore this response.
+ return;
+ }
+
+ // Cancel the update response timeout now that we have the response.
+ update_timer_.Stop();
+ }
+
if (response_code == 200) {
// We have data from the SafeBrowsing service.
parsed_ok = HandleServiceResponse(source->url(),
@@ -524,6 +537,7 @@
if (database_error) {
ScheduleNextUpdate(false);
+ UpdateFinished(false);
return;
}
@@ -566,6 +580,19 @@
request_->set_request_context(Profile::GetDefaultRequestContext());
request_->set_upload_data("text/plain", list_data);
request_->Start();
+
+ // Begin the update request timeout.
+ update_timer_.Start(TimeDelta::FromSeconds(kSbMaxUpdateWaitSec), this,
+ &SafeBrowsingProtocolManager::UpdateResponseTimeout);
+}
+
+// If we haven't heard back from the server with an update response, this method
+// will run. Close the current update session and schedule another update.
+void SafeBrowsingProtocolManager::UpdateResponseTimeout() {
+ DCHECK(request_type_ == UPDATE_REQUEST);
+ request_.reset();
+ ScheduleNextUpdate(false);
+ UpdateFinished(false);
}
void SafeBrowsingProtocolManager::OnChunkInserted() {