OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_cache_transaction.h" | 5 #include "net/http/http_cache_transaction.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 namespace { | 46 namespace { |
47 | 47 |
48 // From http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-21#section-6 | 48 // From http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-21#section-6 |
49 // a "non-error response" is one with a 2xx (Successful) or 3xx | 49 // a "non-error response" is one with a 2xx (Successful) or 3xx |
50 // (Redirection) status code. | 50 // (Redirection) status code. |
51 bool NonErrorResponse(int status_code) { | 51 bool NonErrorResponse(int status_code) { |
52 int status_code_range = status_code / 100; | 52 int status_code_range = status_code / 100; |
53 return status_code_range == 2 || status_code_range == 3; | 53 return status_code_range == 2 || status_code_range == 3; |
54 } | 54 } |
55 | 55 |
56 // Error codes that will be considered indicative of a page being offline/ | |
57 // unreachable for LOAD_FROM_CACHE_IF_OFFLINE. | |
58 bool IsOfflineError(int error) { | |
59 return (error == net::ERR_NAME_NOT_RESOLVED || | |
60 error == net::ERR_INTERNET_DISCONNECTED || | |
61 error == net::ERR_ADDRESS_UNREACHABLE || | |
62 error == net::ERR_CONNECTION_TIMED_OUT); | |
63 } | |
64 | |
56 } // namespace | 65 } // namespace |
57 | 66 |
58 namespace net { | 67 namespace net { |
59 | 68 |
60 struct HeaderNameAndValue { | 69 struct HeaderNameAndValue { |
61 const char* name; | 70 const char* name; |
62 const char* value; | 71 const char* value; |
63 }; | 72 }; |
64 | 73 |
65 // If the request includes one of these request headers, then avoid caching | 74 // If the request includes one of these request headers, then avoid caching |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 target_state_(STATE_NONE), | 142 target_state_(STATE_NONE), |
134 reading_(false), | 143 reading_(false), |
135 invalid_range_(false), | 144 invalid_range_(false), |
136 truncated_(false), | 145 truncated_(false), |
137 is_sparse_(false), | 146 is_sparse_(false), |
138 range_requested_(false), | 147 range_requested_(false), |
139 handling_206_(false), | 148 handling_206_(false), |
140 cache_pending_(false), | 149 cache_pending_(false), |
141 done_reading_(false), | 150 done_reading_(false), |
142 vary_mismatch_(false), | 151 vary_mismatch_(false), |
152 couldnt_conditionalize_request_(false), | |
143 io_buf_len_(0), | 153 io_buf_len_(0), |
144 read_offset_(0), | 154 read_offset_(0), |
145 effective_load_flags_(0), | 155 effective_load_flags_(0), |
146 write_len_(0), | 156 write_len_(0), |
147 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 157 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
148 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( | 158 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( |
149 base::Bind(&Transaction::OnIOComplete, | 159 base::Bind(&Transaction::OnIOComplete, |
150 weak_factory_.GetWeakPtr()))), | 160 weak_factory_.GetWeakPtr()))), |
151 transaction_pattern_(PATTERN_UNDEFINED), | 161 transaction_pattern_(PATTERN_UNDEFINED), |
152 defer_cache_sensitivity_delay_(false), | 162 defer_cache_sensitivity_delay_(false), |
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
803 rv = network_trans_->Start(request_, io_callback_, net_log_); | 813 rv = network_trans_->Start(request_, io_callback_, net_log_); |
804 return rv; | 814 return rv; |
805 } | 815 } |
806 | 816 |
807 int HttpCache::Transaction::DoSendRequestComplete(int result) { | 817 int HttpCache::Transaction::DoSendRequestComplete(int result) { |
808 ReportNetworkActionFinish(); | 818 ReportNetworkActionFinish(); |
809 | 819 |
810 if (!cache_) | 820 if (!cache_) |
811 return ERR_UNEXPECTED; | 821 return ERR_UNEXPECTED; |
812 | 822 |
823 // If requested, and we have a readable cache entry, and we have | |
824 // an error indicating that we're offline as opposed to in contact | |
825 // with a bad server, read from cache anyway. | |
826 if ((effective_load_flags_ & LOAD_FROM_CACHE_IF_OFFLINE) && | |
827 IsOfflineError(result) && mode_ == READ_WRITE && entry_ && !partial_) { | |
828 network_trans_.reset(); | |
829 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
830 | |
831 cache_->ConvertWriterToReader(entry_); | |
832 mode_ = READ; | |
833 response_.was_cache_override = true; | |
834 | |
835 // If there is metadata, read it. Otherwise, we're done. | |
836 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | |
837 next_state_ = STATE_CACHE_READ_METADATA; | |
838 return OK; | |
839 } | |
840 | |
841 // If we tried to conditionalize the request and failed, we know | |
842 // we won't be reading from the cache after this point. | |
843 if (couldnt_conditionalize_request_) | |
844 mode_ = WRITE; | |
845 | |
813 if (result == OK) { | 846 if (result == OK) { |
814 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 847 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
815 return OK; | 848 return OK; |
816 } | 849 } |
817 | 850 |
818 // Do not record requests that have network errors or restarts. | 851 // Do not record requests that have network errors or restarts. |
819 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 852 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
820 if (IsCertificateError(result)) { | 853 if (IsCertificateError(result)) { |
821 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 854 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
822 // If we get a certificate error, then there is a certificate in ssl_info, | 855 // If we get a certificate error, then there is a certificate in ssl_info, |
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1774 } | 1807 } |
1775 } | 1808 } |
1776 cache_->ConvertWriterToReader(entry_); | 1809 cache_->ConvertWriterToReader(entry_); |
1777 mode_ = READ; | 1810 mode_ = READ; |
1778 | 1811 |
1779 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1812 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
1780 next_state_ = STATE_CACHE_READ_METADATA; | 1813 next_state_ = STATE_CACHE_READ_METADATA; |
1781 } else { | 1814 } else { |
1782 // Make the network request conditional, to see if we may reuse our cached | 1815 // Make the network request conditional, to see if we may reuse our cached |
1783 // response. If we cannot do so, then we just resort to a normal fetch. | 1816 // response. If we cannot do so, then we just resort to a normal fetch. |
1784 // Our mode remains READ_WRITE for a conditional request. We'll switch to | 1817 // Our mode remains READ_WRITE for a conditional request. Even if the |
1785 // either READ or WRITE mode once we hear back from the server. | 1818 // conditionalization fails, we don't switch to WRITE mode until we |
1819 // 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.
| |
1820 // LOAD_FROM_CACHE_IF_OFFLINE case. | |
1786 if (!ConditionalizeRequest()) { | 1821 if (!ConditionalizeRequest()) { |
1822 couldnt_conditionalize_request_ = true; | |
1787 UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE); | 1823 UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE); |
1788 if (partial_.get()) | 1824 if (partial_.get()) |
1789 return DoRestartPartialRequest(); | 1825 return DoRestartPartialRequest(); |
1790 | 1826 |
1791 DCHECK_NE(206, response_.headers->response_code()); | 1827 DCHECK_NE(206, response_.headers->response_code()); |
1792 mode_ = WRITE; | |
1793 } | 1828 } |
1794 next_state_ = STATE_SEND_REQUEST; | 1829 next_state_ = STATE_SEND_REQUEST; |
1795 } | 1830 } |
1796 return OK; | 1831 return OK; |
1797 } | 1832 } |
1798 | 1833 |
1799 int HttpCache::Transaction::BeginPartialCacheValidation() { | 1834 int HttpCache::Transaction::BeginPartialCacheValidation() { |
1800 DCHECK(mode_ == READ_WRITE); | 1835 DCHECK(mode_ == READ_WRITE); |
1801 | 1836 |
1802 if (response_.headers->response_code() != 206 && !partial_.get() && | 1837 if (response_.headers->response_code() != 206 && !partial_.get() && |
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2573 entry_path += " -> "; | 2608 entry_path += " -> "; |
2574 entry_path += state_names[*it]; | 2609 entry_path += state_names[*it]; |
2575 } | 2610 } |
2576 LOG(WARNING) << "Path state transitions for " << cache_key_ | 2611 LOG(WARNING) << "Path state transitions for " << cache_key_ |
2577 << ": " << entry_path; | 2612 << ": " << entry_path; |
2578 } | 2613 } |
2579 | 2614 |
2580 #endif | 2615 #endif |
2581 | 2616 |
2582 } // namespace net | 2617 } // namespace net |
OLD | NEW |