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

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 comments. Created 7 years, 9 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
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | net/http/http_cache_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/http_cache_transaction.cc
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 50a9d78db3cd1cf3a21dc7df9de18b818fa080fb..a8b93e388cb0ee5b1acbf03a13d7e19cc55a98e7 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 {
@@ -142,6 +151,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),
@@ -813,6 +823,21 @@ 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_) {
+ UpdateTransactionPattern(PATTERN_NOT_COVERED);
+ response_.server_data_unavailable = true;
+ return SetupEntryForRead();
+ }
+
+ // 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;
@@ -1766,33 +1791,21 @@ int HttpCache::Transaction::BeginCacheValidation() {
if (skip_validation) {
UpdateTransactionPattern(PATTERN_ENTRY_USED);
- if (partial_.get()) {
- if (truncated_ || is_sparse_ || !invalid_range_) {
- // We are going to return the saved response headers to the caller, so
- // we may need to adjust them first.
- next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
- return OK;
- } else {
- partial_.reset();
- }
- }
- cache_->ConvertWriterToReader(entry_);
- mode_ = READ;
-
- if (entry_->disk_entry->GetDataSize(kMetadataIndex))
- next_state_ = STATE_CACHE_READ_METADATA;
+ return SetupEntryForRead();
} 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
+ // know we won't be falling back to using the cache entry in the
+ // 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;
}
@@ -2148,6 +2161,27 @@ void HttpCache::Transaction::FailRangeRequest() {
partial_->FixResponseHeaders(response_.headers, false);
}
+int HttpCache::Transaction::SetupEntryForRead() {
+ network_trans_.reset();
+ if (partial_.get()) {
+ if (truncated_ || is_sparse_ || !invalid_range_) {
+ // We are going to return the saved response headers to the caller, so
+ // we may need to adjust them first.
+ next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
+ return OK;
+ } else {
+ partial_.reset();
+ }
+ }
+ cache_->ConvertWriterToReader(entry_);
+ mode_ = READ;
+
+ if (entry_->disk_entry->GetDataSize(kMetadataIndex))
+ next_state_ = STATE_CACHE_READ_METADATA;
+ return OK;
+}
+
+
int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) {
read_buf_ = data;
io_buf_len_ = data_len;
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | net/http/http_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698