| 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 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 829 response_.server_data_unavailable = true; |
| 830 return SetupEntryForRead(); |
| 831 } |
| 832 |
| 833 // If we tried to conditionalize the request and failed, we know |
| 834 // we won't be reading from the cache after this point. |
| 835 if (couldnt_conditionalize_request_) |
| 836 mode_ = WRITE; |
| 837 |
| 813 if (result == OK) { | 838 if (result == OK) { |
| 814 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 839 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
| 815 return OK; | 840 return OK; |
| 816 } | 841 } |
| 817 | 842 |
| 818 // Do not record requests that have network errors or restarts. | 843 // Do not record requests that have network errors or restarts. |
| 819 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 844 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 820 if (IsCertificateError(result)) { | 845 if (IsCertificateError(result)) { |
| 821 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 846 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
| 822 // If we get a certificate error, then there is a certificate in ssl_info, | 847 // If we get a certificate error, then there is a certificate in ssl_info, |
| (...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1756 if (partial_.get() && (is_sparse_ || truncated_) && | 1781 if (partial_.get() && (is_sparse_ || truncated_) && |
| 1757 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 1782 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
| 1758 // Force revalidation for sparse or truncated entries. Note that we don't | 1783 // Force revalidation for sparse or truncated entries. Note that we don't |
| 1759 // want to ignore the regular validation logic just because a byte range was | 1784 // want to ignore the regular validation logic just because a byte range was |
| 1760 // part of the request. | 1785 // part of the request. |
| 1761 skip_validation = false; | 1786 skip_validation = false; |
| 1762 } | 1787 } |
| 1763 | 1788 |
| 1764 if (skip_validation) { | 1789 if (skip_validation) { |
| 1765 UpdateTransactionPattern(PATTERN_ENTRY_USED); | 1790 UpdateTransactionPattern(PATTERN_ENTRY_USED); |
| 1766 if (partial_.get()) { | 1791 return SetupEntryForRead(); |
| 1767 if (truncated_ || is_sparse_ || !invalid_range_) { | |
| 1768 // We are going to return the saved response headers to the caller, so | |
| 1769 // we may need to adjust them first. | |
| 1770 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | |
| 1771 return OK; | |
| 1772 } else { | |
| 1773 partial_.reset(); | |
| 1774 } | |
| 1775 } | |
| 1776 cache_->ConvertWriterToReader(entry_); | |
| 1777 mode_ = READ; | |
| 1778 | |
| 1779 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | |
| 1780 next_state_ = STATE_CACHE_READ_METADATA; | |
| 1781 } else { | 1792 } else { |
| 1782 // Make the network request conditional, to see if we may reuse our cached | 1793 // 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. | 1794 // 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 | 1795 // 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. | 1796 // conditionalization fails, we don't switch to WRITE mode until we |
| 1797 // know we won't be falling back to using the cache entry in the |
| 1798 // LOAD_FROM_CACHE_IF_OFFLINE case. |
| 1786 if (!ConditionalizeRequest()) { | 1799 if (!ConditionalizeRequest()) { |
| 1800 couldnt_conditionalize_request_ = true; |
| 1787 UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE); | 1801 UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE); |
| 1788 if (partial_.get()) | 1802 if (partial_.get()) |
| 1789 return DoRestartPartialRequest(); | 1803 return DoRestartPartialRequest(); |
| 1790 | 1804 |
| 1791 DCHECK_NE(206, response_.headers->response_code()); | 1805 DCHECK_NE(206, response_.headers->response_code()); |
| 1792 mode_ = WRITE; | |
| 1793 } | 1806 } |
| 1794 next_state_ = STATE_SEND_REQUEST; | 1807 next_state_ = STATE_SEND_REQUEST; |
| 1795 } | 1808 } |
| 1796 return OK; | 1809 return OK; |
| 1797 } | 1810 } |
| 1798 | 1811 |
| 1799 int HttpCache::Transaction::BeginPartialCacheValidation() { | 1812 int HttpCache::Transaction::BeginPartialCacheValidation() { |
| 1800 DCHECK(mode_ == READ_WRITE); | 1813 DCHECK(mode_ == READ_WRITE); |
| 1801 | 1814 |
| 1802 if (response_.headers->response_code() != 206 && !partial_.get() && | 1815 if (response_.headers->response_code() != 206 && !partial_.get() && |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2138 partial_.reset(NULL); | 2151 partial_.reset(NULL); |
| 2139 entry_ = NULL; | 2152 entry_ = NULL; |
| 2140 mode_ = NONE; | 2153 mode_ = NONE; |
| 2141 } | 2154 } |
| 2142 | 2155 |
| 2143 void HttpCache::Transaction::FailRangeRequest() { | 2156 void HttpCache::Transaction::FailRangeRequest() { |
| 2144 response_ = *new_response_; | 2157 response_ = *new_response_; |
| 2145 partial_->FixResponseHeaders(response_.headers, false); | 2158 partial_->FixResponseHeaders(response_.headers, false); |
| 2146 } | 2159 } |
| 2147 | 2160 |
| 2161 int HttpCache::Transaction::SetupEntryForRead() { |
| 2162 network_trans_.reset(); |
| 2163 if (partial_.get()) { |
| 2164 if (truncated_ || is_sparse_ || !invalid_range_) { |
| 2165 // We are going to return the saved response headers to the caller, so |
| 2166 // we may need to adjust them first. |
| 2167 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 2168 return OK; |
| 2169 } else { |
| 2170 partial_.reset(); |
| 2171 } |
| 2172 } |
| 2173 cache_->ConvertWriterToReader(entry_); |
| 2174 mode_ = READ; |
| 2175 |
| 2176 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 2177 next_state_ = STATE_CACHE_READ_METADATA; |
| 2178 return OK; |
| 2179 } |
| 2180 |
| 2181 |
| 2148 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { | 2182 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { |
| 2149 read_buf_ = data; | 2183 read_buf_ = data; |
| 2150 io_buf_len_ = data_len; | 2184 io_buf_len_ = data_len; |
| 2151 next_state_ = STATE_NETWORK_READ; | 2185 next_state_ = STATE_NETWORK_READ; |
| 2152 return DoLoop(OK); | 2186 return DoLoop(OK); |
| 2153 } | 2187 } |
| 2154 | 2188 |
| 2155 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) { | 2189 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) { |
| 2156 read_buf_ = data; | 2190 read_buf_ = data; |
| 2157 io_buf_len_ = data_len; | 2191 io_buf_len_ = data_len; |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2573 entry_path += " -> "; | 2607 entry_path += " -> "; |
| 2574 entry_path += state_names[*it]; | 2608 entry_path += state_names[*it]; |
| 2575 } | 2609 } |
| 2576 LOG(WARNING) << "Path state transitions for " << cache_key_ | 2610 LOG(WARNING) << "Path state transitions for " << cache_key_ |
| 2577 << ": " << entry_path; | 2611 << ": " << entry_path; |
| 2578 } | 2612 } |
| 2579 | 2613 |
| 2580 #endif | 2614 #endif |
| 2581 | 2615 |
| 2582 } // namespace net | 2616 } // namespace net |
| OLD | NEW |