Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Unified Diff: net/http/http_cache_transaction.cc

Issue 12310075: Cache failover to LOAD_PREFERRING_CACHE if network response suggests offline. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Incorporated most comments; responded with questions to a few. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/http/http_cache_transaction.cc
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 3c9953930bcac27131eb50894d2fec174f78b26f..8d0c8d52acc4bf6a702e71a3158c914268641623 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -53,6 +53,15 @@ bool NonErrorResponse(int status_code) {
return status_code_range == 2 || status_code_range == 3;
}
+// Error codes that will be considered indicative of a page being offline/
+// unreachable for LOAD_FROM_CACHE_IF_OFFLINE.
+bool IsOfflineError(int error) {
+ return (error == net::ERR_NAME_NOT_RESOLVED ||
+ error == net::ERR_INTERNET_DISCONNECTED ||
+ error == net::ERR_ADDRESS_UNREACHABLE ||
+ error == net::ERR_CONNECTION_TIMED_OUT);
+}
+
} // namespace
namespace net {
@@ -140,6 +149,7 @@ HttpCache::Transaction::Transaction(
cache_pending_(false),
done_reading_(false),
vary_mismatch_(false),
+ couldnt_conditionalize_request_(false),
io_buf_len_(0),
read_offset_(0),
effective_load_flags_(0),
@@ -810,6 +820,29 @@ int HttpCache::Transaction::DoSendRequestComplete(int result) {
if (!cache_)
return ERR_UNEXPECTED;
+ // If requested, and we have a readable cache entry, and we have
+ // an error indicating that we're offline as opposed to in contact
+ // with a bad server, read from cache anyway.
+ if ((effective_load_flags_ & LOAD_FROM_CACHE_IF_OFFLINE) &&
+ IsOfflineError(result) && mode_ == READ_WRITE && entry_ && !partial_) {
+ network_trans_.reset();
+ UpdateTransactionPattern(PATTERN_NOT_COVERED);
+
+ cache_->ConvertWriterToReader(entry_);
+ mode_ = READ;
+ response_.was_cache_override = true;
+
+ // If there is metadata, read it. Otherwise, we're done.
+ if (entry_->disk_entry->GetDataSize(kMetadataIndex))
+ next_state_ = STATE_CACHE_READ_METADATA;
+ return OK;
+ }
+
+ // If we tried to conditionalize the request and failed, we know
+ // we won't be reading from the cache after this point.
+ if (couldnt_conditionalize_request_)
+ mode_ = WRITE;
+
if (result == OK) {
next_state_ = STATE_SUCCESSFUL_SEND_REQUEST;
return OK;
@@ -1781,15 +1814,17 @@ int HttpCache::Transaction::BeginCacheValidation() {
} else {
// Make the network request conditional, to see if we may reuse our cached
// response. If we cannot do so, then we just resort to a normal fetch.
- // Our mode remains READ_WRITE for a conditional request. We'll switch to
- // either READ or WRITE mode once we hear back from the server.
+ // Our mode remains READ_WRITE for a conditional request. Even if the
+ // conditionalization fails, we don't switch to WRITE mode until we
+ // no we won't be falling back to using the cache entry in the
rvargas (doing something else) 2013/03/06 03:11:48 typo: no we
Randy Smith (Not in Mondays) 2013/03/06 22:55:55 Done.
+ // LOAD_FROM_CACHE_IF_OFFLINE case.
if (!ConditionalizeRequest()) {
+ couldnt_conditionalize_request_ = true;
UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE);
if (partial_.get())
return DoRestartPartialRequest();
DCHECK_NE(206, response_.headers->response_code());
- mode_ = WRITE;
}
next_state_ = STATE_SEND_REQUEST;
}

Powered by Google App Engine
This is Rietveld 408576698