Chromium Code Reviews| 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; |
| } |