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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
164 } | 164 } |
165 | 165 |
166 // From http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-21#section-6 | 166 // From http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-21#section-6 |
167 // a "non-error response" is one with a 2xx (Successful) or 3xx | 167 // a "non-error response" is one with a 2xx (Successful) or 3xx |
168 // (Redirection) status code. | 168 // (Redirection) status code. |
169 bool NonErrorResponse(int status_code) { | 169 bool NonErrorResponse(int status_code) { |
170 int status_code_range = status_code / 100; | 170 int status_code_range = status_code / 100; |
171 return status_code_range == 2 || status_code_range == 3; | 171 return status_code_range == 2 || status_code_range == 3; |
172 } | 172 } |
173 | 173 |
174 // Error codes that will be considered indicative of a page being offline/ | |
175 // unreachable for LOAD_FROM_CACHE_IF_OFFLINE. | |
176 bool IsOfflineError(int error) { | |
177 return (error == net::ERR_NAME_NOT_RESOLVED || | |
178 error == net::ERR_INTERNET_DISCONNECTED || | |
179 error == net::ERR_ADDRESS_UNREACHABLE || | |
180 error == net::ERR_CONNECTION_TIMED_OUT); | |
181 } | |
182 | |
183 // Enum for UMA, indicating the status (with regard to offline mode) of | |
184 // a particular request. | |
185 enum RequestOfflineStatus { | |
186 // A cache transaction hit in cache (data was present and not stale) | |
187 // and returned it. | |
188 OFFLINE_STATUS_FRESH_CACHE, | |
189 | |
190 // A network request was required for a cache entry, and it succeeded. | |
191 OFFLINE_STATUS_NETWORK_SUCCEEDED, | |
192 | |
193 // A network request was required for a cache entry, and it failed with | |
194 // a non-offline error. | |
195 OFFLINE_STATUS_NETWORK_FAILED, | |
196 | |
197 // A network request was required for a cache entry, it failed with an | |
198 // offline error, and we could serve stale data if | |
199 // LOAD_FROM_CACHE_IF_OFFLINE was set. | |
200 OFFLINE_STATUS_DATA_AVAILABLE_OFFLINE, | |
201 | |
202 // A network request was required for a cache entry, it failed with | |
203 // an offline error, and there was no servable data in cache (even | |
204 // stale data). | |
205 OFFLINE_STATUS_DATA_UNAVAILABLE_OFFLINE, | |
206 | |
207 OFFLINE_STATUS_MAX_ENTRIES | |
208 }; | |
209 | |
210 void RecordOfflineStatus(int load_flags, RequestOfflineStatus status) { | |
211 // Restrict to main frame to keep statistics close to | |
212 // "would have shown them something useful if offline mode was enabled". | |
213 if (load_flags & net::LOAD_MAIN_FRAME) { | |
214 UMA_HISTOGRAM_ENUMERATION("HttpCache.OfflineStatus", status, | |
215 OFFLINE_STATUS_MAX_ENTRIES); | |
216 } | |
217 } | |
218 | |
219 void RecordNoStoreHeaderHistogram(int load_flags, | 174 void RecordNoStoreHeaderHistogram(int load_flags, |
220 const net::HttpResponseInfo* response) { | 175 const net::HttpResponseInfo* response) { |
221 if (load_flags & net::LOAD_MAIN_FRAME) { | 176 if (load_flags & net::LOAD_MAIN_FRAME) { |
222 UMA_HISTOGRAM_BOOLEAN( | 177 UMA_HISTOGRAM_BOOLEAN( |
223 "Net.MainFrameNoStore", | 178 "Net.MainFrameNoStore", |
224 response->headers->HasHeaderValue("cache-control", "no-store")); | 179 response->headers->HasHeaderValue("cache-control", "no-store")); |
225 } | 180 } |
226 } | 181 } |
227 | 182 |
228 base::Value* NetLogAsyncRevalidationInfoCallback( | 183 base::Value* NetLogAsyncRevalidationInfoCallback( |
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1109 | 1064 |
1110 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 1065 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
1111 rv = network_trans_->Start(request_, io_callback_, net_log_); | 1066 rv = network_trans_->Start(request_, io_callback_, net_log_); |
1112 return rv; | 1067 return rv; |
1113 } | 1068 } |
1114 | 1069 |
1115 int HttpCache::Transaction::DoSendRequestComplete(int result) { | 1070 int HttpCache::Transaction::DoSendRequestComplete(int result) { |
1116 if (!cache_.get()) | 1071 if (!cache_.get()) |
1117 return ERR_UNEXPECTED; | 1072 return ERR_UNEXPECTED; |
1118 | 1073 |
1119 // If requested, and we have a readable cache entry, and we have | |
1120 // an error indicating that we're offline as opposed to in contact | |
1121 // with a bad server, read from cache anyway. | |
1122 if (IsOfflineError(result)) { | |
1123 if (mode_ == READ_WRITE && entry_ && !partial_) { | |
1124 RecordOfflineStatus(effective_load_flags_, | |
1125 OFFLINE_STATUS_DATA_AVAILABLE_OFFLINE); | |
1126 if (effective_load_flags_ & LOAD_FROM_CACHE_IF_OFFLINE) { | |
1127 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
1128 response_.server_data_unavailable = true; | |
1129 return SetupEntryForRead(); | |
kbalazs
2015/04/24 20:54:55
Are you sure you want to remove this? This seem to
mmenke
2015/04/24 21:02:52
It's only set when LOAD_FROM_CACHE_IF_OFFLINE is s
| |
1130 } | |
1131 } else { | |
1132 RecordOfflineStatus(effective_load_flags_, | |
1133 OFFLINE_STATUS_DATA_UNAVAILABLE_OFFLINE); | |
1134 } | |
1135 } else { | |
1136 RecordOfflineStatus(effective_load_flags_, | |
1137 (result == OK ? OFFLINE_STATUS_NETWORK_SUCCEEDED : | |
1138 OFFLINE_STATUS_NETWORK_FAILED)); | |
1139 } | |
1140 | |
1141 // If we tried to conditionalize the request and failed, we know | 1074 // If we tried to conditionalize the request and failed, we know |
1142 // we won't be reading from the cache after this point. | 1075 // we won't be reading from the cache after this point. |
1143 if (couldnt_conditionalize_request_) | 1076 if (couldnt_conditionalize_request_) |
1144 mode_ = WRITE; | 1077 mode_ = WRITE; |
1145 | 1078 |
1146 if (result == OK) { | 1079 if (result == OK) { |
1147 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 1080 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
1148 return OK; | 1081 return OK; |
1149 } | 1082 } |
1150 | 1083 |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2219 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 2152 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
2220 // Force revalidation for sparse or truncated entries. Note that we don't | 2153 // Force revalidation for sparse or truncated entries. Note that we don't |
2221 // want to ignore the regular validation logic just because a byte range was | 2154 // want to ignore the regular validation logic just because a byte range was |
2222 // part of the request. | 2155 // part of the request. |
2223 skip_validation = false; | 2156 skip_validation = false; |
2224 } | 2157 } |
2225 | 2158 |
2226 if (skip_validation) { | 2159 if (skip_validation) { |
2227 // TODO(ricea): Is this pattern okay for asynchronous revalidations? | 2160 // TODO(ricea): Is this pattern okay for asynchronous revalidations? |
2228 UpdateTransactionPattern(PATTERN_ENTRY_USED); | 2161 UpdateTransactionPattern(PATTERN_ENTRY_USED); |
2229 RecordOfflineStatus(effective_load_flags_, OFFLINE_STATUS_FRESH_CACHE); | |
2230 return SetupEntryForRead(); | 2162 return SetupEntryForRead(); |
2231 } else { | 2163 } else { |
2232 // Make the network request conditional, to see if we may reuse our cached | 2164 // Make the network request conditional, to see if we may reuse our cached |
2233 // response. If we cannot do so, then we just resort to a normal fetch. | 2165 // response. If we cannot do so, then we just resort to a normal fetch. |
2234 // Our mode remains READ_WRITE for a conditional request. Even if the | 2166 // Our mode remains READ_WRITE for a conditional request. Even if the |
2235 // conditionalization fails, we don't switch to WRITE mode until we | 2167 // conditionalization fails, we don't switch to WRITE mode until we |
2236 // know we won't be falling back to using the cache entry in the | 2168 // know we won't be falling back to using the cache entry in the |
2237 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2169 // LOAD_FROM_CACHE_IF_OFFLINE case. |
2238 if (!ConditionalizeRequest()) { | 2170 if (!ConditionalizeRequest()) { |
2239 couldnt_conditionalize_request_ = true; | 2171 couldnt_conditionalize_request_ = true; |
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3032 default: | 2964 default: |
3033 NOTREACHED(); | 2965 NOTREACHED(); |
3034 } | 2966 } |
3035 } | 2967 } |
3036 | 2968 |
3037 void HttpCache::Transaction::OnIOComplete(int result) { | 2969 void HttpCache::Transaction::OnIOComplete(int result) { |
3038 DoLoop(result); | 2970 DoLoop(result); |
3039 } | 2971 } |
3040 | 2972 |
3041 } // namespace net | 2973 } // namespace net |
OLD | NEW |