| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 | 80 |
| 81 // A network request was required for a cache entry, it failed with an | 81 // A network request was required for a cache entry, it failed with an |
| 82 // offline error, and we could serve stale data if | 82 // offline error, and we could serve stale data if |
| 83 // LOAD_FROM_CACHE_IF_OFFLINE was set. | 83 // LOAD_FROM_CACHE_IF_OFFLINE was set. |
| 84 OFFLINE_STATUS_DATA_AVAILABLE_OFFLINE, | 84 OFFLINE_STATUS_DATA_AVAILABLE_OFFLINE, |
| 85 | 85 |
| 86 // A network request was required for a cache entry, it failed with | 86 // A network request was required for a cache entry, it failed with |
| 87 // an offline error, and there was no servable data in cache (even | 87 // an offline error, and there was no servable data in cache (even |
| 88 // stale data). | 88 // stale data). |
| 89 OFFLINE_STATUS_DATA_UNAVAILABLE_OFFLINE, | 89 OFFLINE_STATUS_DATA_UNAVAILABLE_OFFLINE, |
| 90 | |
| 91 OFFLINE_STATUS_MAX_ENTRIES | 90 OFFLINE_STATUS_MAX_ENTRIES |
| 92 }; | 91 }; |
| 93 | 92 |
| 94 void RecordOfflineStatus(int load_flags, RequestOfflineStatus status) { | 93 void RecordOfflineStatus(int load_flags, RequestOfflineStatus status) { |
| 95 // Restrict to main frame to keep statistics close to | 94 // Restrict to main frame to keep statistics close to |
| 96 // "would have shown them something useful if offline mode was enabled". | 95 // "would have shown them something useful if offline mode was enabled". |
| 97 if (load_flags & net::LOAD_MAIN_FRAME) { | 96 if (load_flags & net::LOAD_MAIN_FRAME) { |
| 98 UMA_HISTOGRAM_ENUMERATION("HttpCache.OfflineStatus", status, | 97 UMA_HISTOGRAM_ENUMERATION( |
| 99 OFFLINE_STATUS_MAX_ENTRIES); | 98 "HttpCache.OfflineStatus", status, OFFLINE_STATUS_MAX_ENTRIES); |
| 100 } | 99 } |
| 101 } | 100 } |
| 102 | 101 |
| 103 // TODO(rvargas): Remove once we get the data. | 102 // TODO(rvargas): Remove once we get the data. |
| 104 void RecordVaryHeaderHistogram(const net::HttpResponseInfo* response) { | 103 void RecordVaryHeaderHistogram(const net::HttpResponseInfo* response) { |
| 105 enum VaryType { | 104 enum VaryType { VARY_NOT_PRESENT, VARY_UA, VARY_OTHER, VARY_MAX }; |
| 106 VARY_NOT_PRESENT, | |
| 107 VARY_UA, | |
| 108 VARY_OTHER, | |
| 109 VARY_MAX | |
| 110 }; | |
| 111 VaryType vary = VARY_NOT_PRESENT; | 105 VaryType vary = VARY_NOT_PRESENT; |
| 112 if (response->vary_data.is_valid()) { | 106 if (response->vary_data.is_valid()) { |
| 113 vary = VARY_OTHER; | 107 vary = VARY_OTHER; |
| 114 if (response->headers->HasHeaderValue("vary", "user-agent")) | 108 if (response->headers->HasHeaderValue("vary", "user-agent")) |
| 115 vary = VARY_UA; | 109 vary = VARY_UA; |
| 116 } | 110 } |
| 117 UMA_HISTOGRAM_ENUMERATION("HttpCache.Vary", vary, VARY_MAX); | 111 UMA_HISTOGRAM_ENUMERATION("HttpCache.Vary", vary, VARY_MAX); |
| 118 } | 112 } |
| 119 | 113 |
| 120 } // namespace | 114 } // namespace |
| 121 | 115 |
| 122 namespace net { | 116 namespace net { |
| 123 | 117 |
| 124 struct HeaderNameAndValue { | 118 struct HeaderNameAndValue { |
| 125 const char* name; | 119 const char* name; |
| 126 const char* value; | 120 const char* value; |
| 127 }; | 121 }; |
| 128 | 122 |
| 129 // If the request includes one of these request headers, then avoid caching | 123 // If the request includes one of these request headers, then avoid caching |
| 130 // to avoid getting confused. | 124 // to avoid getting confused. |
| 131 static const HeaderNameAndValue kPassThroughHeaders[] = { | 125 static const HeaderNameAndValue kPassThroughHeaders[] = { |
| 132 { "if-unmodified-since", NULL }, // causes unexpected 412s | 126 {"if-unmodified-since", NULL}, // causes unexpected 412s |
| 133 { "if-match", NULL }, // causes unexpected 412s | 127 {"if-match", NULL}, // causes unexpected 412s |
| 134 { "if-range", NULL }, | 128 {"if-range", NULL}, |
| 135 { NULL, NULL } | 129 {NULL, NULL}}; |
| 136 }; | |
| 137 | 130 |
| 138 struct ValidationHeaderInfo { | 131 struct ValidationHeaderInfo { |
| 139 const char* request_header_name; | 132 const char* request_header_name; |
| 140 const char* related_response_header_name; | 133 const char* related_response_header_name; |
| 141 }; | 134 }; |
| 142 | 135 |
| 143 static const ValidationHeaderInfo kValidationHeaders[] = { | 136 static const ValidationHeaderInfo kValidationHeaders[] = { |
| 144 { "if-modified-since", "last-modified" }, | 137 {"if-modified-since", "last-modified"}, |
| 145 { "if-none-match", "etag" }, | 138 {"if-none-match", "etag"}, |
| 146 }; | 139 }; |
| 147 | 140 |
| 148 // If the request includes one of these request headers, then avoid reusing | 141 // If the request includes one of these request headers, then avoid reusing |
| 149 // our cached copy if any. | 142 // our cached copy if any. |
| 150 static const HeaderNameAndValue kForceFetchHeaders[] = { | 143 static const HeaderNameAndValue kForceFetchHeaders[] = { |
| 151 { "cache-control", "no-cache" }, | 144 {"cache-control", "no-cache"}, |
| 152 { "pragma", "no-cache" }, | 145 {"pragma", "no-cache"}, |
| 153 { NULL, NULL } | 146 {NULL, NULL}}; |
| 154 }; | |
| 155 | 147 |
| 156 // If the request includes one of these request headers, then force our | 148 // If the request includes one of these request headers, then force our |
| 157 // cached copy (if any) to be revalidated before reusing it. | 149 // cached copy (if any) to be revalidated before reusing it. |
| 158 static const HeaderNameAndValue kForceValidateHeaders[] = { | 150 static const HeaderNameAndValue kForceValidateHeaders[] = { |
| 159 { "cache-control", "max-age=0" }, | 151 {"cache-control", "max-age=0"}, |
| 160 { NULL, NULL } | 152 {NULL, NULL}}; |
| 161 }; | |
| 162 | 153 |
| 163 static bool HeaderMatches(const HttpRequestHeaders& headers, | 154 static bool HeaderMatches(const HttpRequestHeaders& headers, |
| 164 const HeaderNameAndValue* search) { | 155 const HeaderNameAndValue* search) { |
| 165 for (; search->name; ++search) { | 156 for (; search->name; ++search) { |
| 166 std::string header_value; | 157 std::string header_value; |
| 167 if (!headers.GetHeader(search->name, &header_value)) | 158 if (!headers.GetHeader(search->name, &header_value)) |
| 168 continue; | 159 continue; |
| 169 | 160 |
| 170 if (!search->value) | 161 if (!search->value) |
| 171 return true; | 162 return true; |
| 172 | 163 |
| 173 HttpUtil::ValuesIterator v(header_value.begin(), header_value.end(), ','); | 164 HttpUtil::ValuesIterator v(header_value.begin(), header_value.end(), ','); |
| 174 while (v.GetNext()) { | 165 while (v.GetNext()) { |
| 175 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value)) | 166 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value)) |
| 176 return true; | 167 return true; |
| 177 } | 168 } |
| 178 } | 169 } |
| 179 return false; | 170 return false; |
| 180 } | 171 } |
| 181 | 172 |
| 182 //----------------------------------------------------------------------------- | 173 //----------------------------------------------------------------------------- |
| 183 | 174 |
| 184 HttpCache::Transaction::Transaction( | 175 HttpCache::Transaction::Transaction(RequestPriority priority, HttpCache* cache) |
| 185 RequestPriority priority, | |
| 186 HttpCache* cache) | |
| 187 : next_state_(STATE_NONE), | 176 : next_state_(STATE_NONE), |
| 188 request_(NULL), | 177 request_(NULL), |
| 189 priority_(priority), | 178 priority_(priority), |
| 190 cache_(cache->AsWeakPtr()), | 179 cache_(cache->AsWeakPtr()), |
| 191 entry_(NULL), | 180 entry_(NULL), |
| 192 new_entry_(NULL), | 181 new_entry_(NULL), |
| 193 new_response_(NULL), | 182 new_response_(NULL), |
| 194 mode_(NONE), | 183 mode_(NONE), |
| 195 target_state_(STATE_NONE), | 184 target_state_(STATE_NONE), |
| 196 reading_(false), | 185 reading_(false), |
| 197 invalid_range_(false), | 186 invalid_range_(false), |
| 198 truncated_(false), | 187 truncated_(false), |
| 199 is_sparse_(false), | 188 is_sparse_(false), |
| 200 range_requested_(false), | 189 range_requested_(false), |
| 201 handling_206_(false), | 190 handling_206_(false), |
| 202 cache_pending_(false), | 191 cache_pending_(false), |
| 203 done_reading_(false), | 192 done_reading_(false), |
| 204 vary_mismatch_(false), | 193 vary_mismatch_(false), |
| 205 couldnt_conditionalize_request_(false), | 194 couldnt_conditionalize_request_(false), |
| 206 io_buf_len_(0), | 195 io_buf_len_(0), |
| 207 read_offset_(0), | 196 read_offset_(0), |
| 208 effective_load_flags_(0), | 197 effective_load_flags_(0), |
| 209 write_len_(0), | 198 write_len_(0), |
| 210 weak_factory_(this), | 199 weak_factory_(this), |
| 211 io_callback_(base::Bind(&Transaction::OnIOComplete, | 200 io_callback_( |
| 212 weak_factory_.GetWeakPtr())), | 201 base::Bind(&Transaction::OnIOComplete, weak_factory_.GetWeakPtr())), |
| 213 transaction_pattern_(PATTERN_UNDEFINED), | 202 transaction_pattern_(PATTERN_UNDEFINED), |
| 214 total_received_bytes_(0), | 203 total_received_bytes_(0), |
| 215 websocket_handshake_stream_base_create_helper_(NULL) { | 204 websocket_handshake_stream_base_create_helper_(NULL) { |
| 216 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == | 205 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == |
| 217 arraysize(kValidationHeaders), | 206 arraysize(kValidationHeaders), |
| 218 Invalid_number_of_validation_headers); | 207 Invalid_number_of_validation_headers); |
| 219 } | 208 } |
| 220 | 209 |
| 221 HttpCache::Transaction::~Transaction() { | 210 HttpCache::Transaction::~Transaction() { |
| 222 // We may have to issue another IO, but we should never invoke the callback_ | 211 // We may have to issue another IO, but we should never invoke the callback_ |
| 223 // after this point. | 212 // after this point. |
| 224 callback_.Reset(); | 213 callback_.Reset(); |
| 225 | 214 |
| 226 if (cache_) { | 215 if (cache_) { |
| 227 if (entry_) { | 216 if (entry_) { |
| 228 bool cancel_request = reading_ && response_.headers; | 217 bool cancel_request = reading_ && response_.headers; |
| 229 if (cancel_request) { | 218 if (cancel_request) { |
| 230 if (partial_) { | 219 if (partial_) { |
| 231 entry_->disk_entry->CancelSparseIO(); | 220 entry_->disk_entry->CancelSparseIO(); |
| 232 } else { | 221 } else { |
| 233 cancel_request &= (response_.headers->response_code() == 200); | 222 cancel_request &= (response_.headers->response_code() == 200); |
| 234 } | 223 } |
| 235 } | 224 } |
| 236 | 225 |
| 237 cache_->DoneWithEntry(entry_, this, cancel_request); | 226 cache_->DoneWithEntry(entry_, this, cancel_request); |
| 238 } else if (cache_pending_) { | 227 } else if (cache_pending_) { |
| 239 cache_->RemovePendingTransaction(this); | 228 cache_->RemovePendingTransaction(this); |
| 240 } | 229 } |
| 241 } | 230 } |
| 242 } | 231 } |
| 243 | 232 |
| 244 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, | 233 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, |
| 234 int buf_len, |
| 245 const CompletionCallback& callback) { | 235 const CompletionCallback& callback) { |
| 246 DCHECK(buf); | 236 DCHECK(buf); |
| 247 DCHECK_GT(buf_len, 0); | 237 DCHECK_GT(buf_len, 0); |
| 248 DCHECK(!callback.is_null()); | 238 DCHECK(!callback.is_null()); |
| 249 if (!cache_.get() || !entry_) | 239 if (!cache_.get() || !entry_) |
| 250 return ERR_UNEXPECTED; | 240 return ERR_UNEXPECTED; |
| 251 | 241 |
| 252 // We don't need to track this operation for anything. | 242 // We don't need to track this operation for anything. |
| 253 // It could be possible to check if there is something already written and | 243 // It could be possible to check if there is something already written and |
| 254 // avoid writing again (it should be the same, right?), but let's allow the | 244 // avoid writing again (it should be the same, right?), but let's allow the |
| 255 // caller to "update" the contents with something new. | 245 // caller to "update" the contents with something new. |
| 256 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, | 246 return entry_->disk_entry->WriteData( |
| 257 callback, true); | 247 kMetadataIndex, 0, buf, buf_len, callback, true); |
| 258 } | 248 } |
| 259 | 249 |
| 260 bool HttpCache::Transaction::AddTruncatedFlag() { | 250 bool HttpCache::Transaction::AddTruncatedFlag() { |
| 261 DCHECK(mode_ & WRITE || mode_ == NONE); | 251 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 262 | 252 |
| 263 // Don't set the flag for sparse entries. | 253 // Don't set the flag for sparse entries. |
| 264 if (partial_.get() && !truncated_) | 254 if (partial_.get() && !truncated_) |
| 265 return true; | 255 return true; |
| 266 | 256 |
| 267 if (!CanResume(true)) | 257 if (!CanResume(true)) |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 | 368 |
| 379 return rv; | 369 return rv; |
| 380 } | 370 } |
| 381 | 371 |
| 382 bool HttpCache::Transaction::IsReadyToRestartForAuth() { | 372 bool HttpCache::Transaction::IsReadyToRestartForAuth() { |
| 383 if (!network_trans_.get()) | 373 if (!network_trans_.get()) |
| 384 return false; | 374 return false; |
| 385 return network_trans_->IsReadyToRestartForAuth(); | 375 return network_trans_->IsReadyToRestartForAuth(); |
| 386 } | 376 } |
| 387 | 377 |
| 388 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, | 378 int HttpCache::Transaction::Read(IOBuffer* buf, |
| 379 int buf_len, |
| 389 const CompletionCallback& callback) { | 380 const CompletionCallback& callback) { |
| 390 DCHECK(buf); | 381 DCHECK(buf); |
| 391 DCHECK_GT(buf_len, 0); | 382 DCHECK_GT(buf_len, 0); |
| 392 DCHECK(!callback.is_null()); | 383 DCHECK(!callback.is_null()); |
| 393 | 384 |
| 394 DCHECK(callback_.is_null()); | 385 DCHECK(callback_.is_null()); |
| 395 | 386 |
| 396 if (!cache_.get()) | 387 if (!cache_.get()) |
| 397 return ERR_UNEXPECTED; | 388 return ERR_UNEXPECTED; |
| 398 | 389 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 return LOAD_STATE_IDLE; | 498 return LOAD_STATE_IDLE; |
| 508 } | 499 } |
| 509 | 500 |
| 510 UploadProgress HttpCache::Transaction::GetUploadProgress() const { | 501 UploadProgress HttpCache::Transaction::GetUploadProgress() const { |
| 511 if (network_trans_.get()) | 502 if (network_trans_.get()) |
| 512 return network_trans_->GetUploadProgress(); | 503 return network_trans_->GetUploadProgress(); |
| 513 return final_upload_progress_; | 504 return final_upload_progress_; |
| 514 } | 505 } |
| 515 | 506 |
| 516 void HttpCache::Transaction::SetQuicServerInfo( | 507 void HttpCache::Transaction::SetQuicServerInfo( |
| 517 QuicServerInfo* quic_server_info) {} | 508 QuicServerInfo* quic_server_info) { |
| 509 } |
| 518 | 510 |
| 519 bool HttpCache::Transaction::GetLoadTimingInfo( | 511 bool HttpCache::Transaction::GetLoadTimingInfo( |
| 520 LoadTimingInfo* load_timing_info) const { | 512 LoadTimingInfo* load_timing_info) const { |
| 521 if (network_trans_) | 513 if (network_trans_) |
| 522 return network_trans_->GetLoadTimingInfo(load_timing_info); | 514 return network_trans_->GetLoadTimingInfo(load_timing_info); |
| 523 | 515 |
| 524 if (old_network_trans_load_timing_) { | 516 if (old_network_trans_load_timing_) { |
| 525 *load_timing_info = *old_network_trans_load_timing_; | 517 *load_timing_info = *old_network_trans_load_timing_; |
| 526 return true; | 518 return true; |
| 527 } | 519 } |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 return OK; | 864 return OK; |
| 873 } | 865 } |
| 874 | 866 |
| 875 int HttpCache::Transaction::DoSendRequest() { | 867 int HttpCache::Transaction::DoSendRequest() { |
| 876 DCHECK(mode_ & WRITE || mode_ == NONE); | 868 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 877 DCHECK(!network_trans_.get()); | 869 DCHECK(!network_trans_.get()); |
| 878 | 870 |
| 879 send_request_since_ = TimeTicks::Now(); | 871 send_request_since_ = TimeTicks::Now(); |
| 880 | 872 |
| 881 // Create a network transaction. | 873 // Create a network transaction. |
| 882 int rv = cache_->network_layer_->CreateTransaction(priority_, | 874 int rv = |
| 883 &network_trans_); | 875 cache_->network_layer_->CreateTransaction(priority_, &network_trans_); |
| 884 if (rv != OK) | 876 if (rv != OK) |
| 885 return rv; | 877 return rv; |
| 886 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_); | 878 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_); |
| 887 | 879 |
| 888 // Old load timing information, if any, is now obsolete. | 880 // Old load timing information, if any, is now obsolete. |
| 889 old_network_trans_load_timing_.reset(); | 881 old_network_trans_load_timing_.reset(); |
| 890 | 882 |
| 891 if (websocket_handshake_stream_base_create_helper_) | 883 if (websocket_handshake_stream_base_create_helper_) |
| 892 network_trans_->SetWebSocketHandshakeStreamCreateHelper( | 884 network_trans_->SetWebSocketHandshakeStreamCreateHelper( |
| 893 websocket_handshake_stream_base_create_helper_); | 885 websocket_handshake_stream_base_create_helper_); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 912 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 904 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 913 response_.server_data_unavailable = true; | 905 response_.server_data_unavailable = true; |
| 914 return SetupEntryForRead(); | 906 return SetupEntryForRead(); |
| 915 } | 907 } |
| 916 } else { | 908 } else { |
| 917 RecordOfflineStatus(effective_load_flags_, | 909 RecordOfflineStatus(effective_load_flags_, |
| 918 OFFLINE_STATUS_DATA_UNAVAILABLE_OFFLINE); | 910 OFFLINE_STATUS_DATA_UNAVAILABLE_OFFLINE); |
| 919 } | 911 } |
| 920 } else { | 912 } else { |
| 921 RecordOfflineStatus(effective_load_flags_, | 913 RecordOfflineStatus(effective_load_flags_, |
| 922 (result == OK ? OFFLINE_STATUS_NETWORK_SUCCEEDED : | 914 (result == OK ? OFFLINE_STATUS_NETWORK_SUCCEEDED |
| 923 OFFLINE_STATUS_NETWORK_FAILED)); | 915 : OFFLINE_STATUS_NETWORK_FAILED)); |
| 924 } | 916 } |
| 925 | 917 |
| 926 // If we tried to conditionalize the request and failed, we know | 918 // If we tried to conditionalize the request and failed, we know |
| 927 // we won't be reading from the cache after this point. | 919 // we won't be reading from the cache after this point. |
| 928 if (couldnt_conditionalize_request_) | 920 if (couldnt_conditionalize_request_) |
| 929 mode_ = WRITE; | 921 mode_ = WRITE; |
| 930 | 922 |
| 931 if (result == OK) { | 923 if (result == OK) { |
| 932 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 924 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
| 933 return OK; | 925 return OK; |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 if (handling_206_ && !CanResume(false)) { | 1345 if (handling_206_ && !CanResume(false)) { |
| 1354 // There is no point in storing this resource because it will never be used. | 1346 // There is no point in storing this resource because it will never be used. |
| 1355 DoneWritingToEntry(false); | 1347 DoneWritingToEntry(false); |
| 1356 if (partial_.get()) | 1348 if (partial_.get()) |
| 1357 partial_->FixResponseHeaders(response_.headers.get(), true); | 1349 partial_->FixResponseHeaders(response_.headers.get(), true); |
| 1358 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1350 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1359 return OK; | 1351 return OK; |
| 1360 } | 1352 } |
| 1361 | 1353 |
| 1362 target_state_ = STATE_TRUNCATE_CACHED_DATA; | 1354 target_state_ = STATE_TRUNCATE_CACHED_DATA; |
| 1363 next_state_ = truncated_ ? STATE_CACHE_WRITE_TRUNCATED_RESPONSE : | 1355 next_state_ = truncated_ ? STATE_CACHE_WRITE_TRUNCATED_RESPONSE |
| 1364 STATE_CACHE_WRITE_RESPONSE; | 1356 : STATE_CACHE_WRITE_RESPONSE; |
| 1365 return OK; | 1357 return OK; |
| 1366 } | 1358 } |
| 1367 | 1359 |
| 1368 int HttpCache::Transaction::DoTruncateCachedData() { | 1360 int HttpCache::Transaction::DoTruncateCachedData() { |
| 1369 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; | 1361 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; |
| 1370 if (!entry_) | 1362 if (!entry_) |
| 1371 return OK; | 1363 return OK; |
| 1372 if (net_log_.IsLogging()) | 1364 if (net_log_.IsLogging()) |
| 1373 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_DATA); | 1365 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_DATA); |
| 1374 // Truncate the stream. | 1366 // Truncate the stream. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1433 } | 1425 } |
| 1434 | 1426 |
| 1435 int HttpCache::Transaction::DoCacheReadResponse() { | 1427 int HttpCache::Transaction::DoCacheReadResponse() { |
| 1436 DCHECK(entry_); | 1428 DCHECK(entry_); |
| 1437 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE; | 1429 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE; |
| 1438 | 1430 |
| 1439 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex); | 1431 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex); |
| 1440 read_buf_ = new IOBuffer(io_buf_len_); | 1432 read_buf_ = new IOBuffer(io_buf_len_); |
| 1441 | 1433 |
| 1442 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); | 1434 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
| 1443 return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(), | 1435 return entry_->disk_entry->ReadData( |
| 1444 io_buf_len_, io_callback_); | 1436 kResponseInfoIndex, 0, read_buf_.get(), io_buf_len_, io_callback_); |
| 1445 } | 1437 } |
| 1446 | 1438 |
| 1447 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { | 1439 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { |
| 1448 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1440 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
| 1449 if (result != io_buf_len_ || | 1441 if (result != io_buf_len_ || |
| 1450 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, | 1442 !HttpCache::ParseResponseInfo( |
| 1451 &response_, &truncated_)) { | 1443 read_buf_->data(), io_buf_len_, &response_, &truncated_)) { |
| 1452 return OnCacheReadError(result, true); | 1444 return OnCacheReadError(result, true); |
| 1453 } | 1445 } |
| 1454 | 1446 |
| 1455 // Some resources may have slipped in as truncated when they're not. | 1447 // Some resources may have slipped in as truncated when they're not. |
| 1456 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 1448 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1457 if (response_.headers->GetContentLength() == current_size) | 1449 if (response_.headers->GetContentLength() == current_size) |
| 1458 truncated_ = false; | 1450 truncated_ = false; |
| 1459 | 1451 |
| 1460 // We now have access to the cache entry. | 1452 // We now have access to the cache entry. |
| 1461 // | 1453 // |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1525 | 1517 |
| 1526 int HttpCache::Transaction::DoCacheReadMetadata() { | 1518 int HttpCache::Transaction::DoCacheReadMetadata() { |
| 1527 DCHECK(entry_); | 1519 DCHECK(entry_); |
| 1528 DCHECK(!response_.metadata.get()); | 1520 DCHECK(!response_.metadata.get()); |
| 1529 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; | 1521 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; |
| 1530 | 1522 |
| 1531 response_.metadata = | 1523 response_.metadata = |
| 1532 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); | 1524 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); |
| 1533 | 1525 |
| 1534 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); | 1526 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
| 1535 return entry_->disk_entry->ReadData(kMetadataIndex, 0, | 1527 return entry_->disk_entry->ReadData(kMetadataIndex, |
| 1528 0, |
| 1536 response_.metadata.get(), | 1529 response_.metadata.get(), |
| 1537 response_.metadata->size(), | 1530 response_.metadata->size(), |
| 1538 io_callback_); | 1531 io_callback_); |
| 1539 } | 1532 } |
| 1540 | 1533 |
| 1541 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { | 1534 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { |
| 1542 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1535 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
| 1543 if (result != response_.metadata->size()) | 1536 if (result != response_.metadata->size()) |
| 1544 return OnCacheReadError(result, false); | 1537 return OnCacheReadError(result, false); |
| 1545 return OK; | 1538 return OK; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1564 return ValidateEntryHeadersAndContinue(); | 1557 return ValidateEntryHeadersAndContinue(); |
| 1565 } | 1558 } |
| 1566 | 1559 |
| 1567 int HttpCache::Transaction::DoCacheReadData() { | 1560 int HttpCache::Transaction::DoCacheReadData() { |
| 1568 DCHECK(entry_); | 1561 DCHECK(entry_); |
| 1569 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; | 1562 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; |
| 1570 | 1563 |
| 1571 if (net_log_.IsLogging()) | 1564 if (net_log_.IsLogging()) |
| 1572 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA); | 1565 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA); |
| 1573 if (partial_.get()) { | 1566 if (partial_.get()) { |
| 1574 return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_, | 1567 return partial_->CacheRead( |
| 1575 io_callback_); | 1568 entry_->disk_entry, read_buf_.get(), io_buf_len_, io_callback_); |
| 1576 } | 1569 } |
| 1577 | 1570 |
| 1578 return entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_, | 1571 return entry_->disk_entry->ReadData(kResponseContentIndex, |
| 1579 read_buf_.get(), io_buf_len_, | 1572 read_offset_, |
| 1573 read_buf_.get(), |
| 1574 io_buf_len_, |
| 1580 io_callback_); | 1575 io_callback_); |
| 1581 } | 1576 } |
| 1582 | 1577 |
| 1583 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { | 1578 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { |
| 1584 if (net_log_.IsLogging()) { | 1579 if (net_log_.IsLogging()) { |
| 1585 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, | 1580 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, |
| 1586 result); | 1581 result); |
| 1587 } | 1582 } |
| 1588 | 1583 |
| 1589 if (!cache_.get()) | 1584 if (!cache_.get()) |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1695 // LOAD_BYPASS_CACHE : no cache read | 1690 // LOAD_BYPASS_CACHE : no cache read |
| 1696 // LOAD_VALIDATE_CACHE : no cache read unless validation | 1691 // LOAD_VALIDATE_CACHE : no cache read unless validation |
| 1697 // | 1692 // |
| 1698 // The former modes trump latter modes, so if we find a matching header we | 1693 // The former modes trump latter modes, so if we find a matching header we |
| 1699 // can stop iterating kSpecialHeaders. | 1694 // can stop iterating kSpecialHeaders. |
| 1700 // | 1695 // |
| 1701 static const struct { | 1696 static const struct { |
| 1702 const HeaderNameAndValue* search; | 1697 const HeaderNameAndValue* search; |
| 1703 int load_flag; | 1698 int load_flag; |
| 1704 } kSpecialHeaders[] = { | 1699 } kSpecialHeaders[] = { |
| 1705 { kPassThroughHeaders, LOAD_DISABLE_CACHE }, | 1700 {kPassThroughHeaders, LOAD_DISABLE_CACHE}, |
| 1706 { kForceFetchHeaders, LOAD_BYPASS_CACHE }, | 1701 {kForceFetchHeaders, LOAD_BYPASS_CACHE}, |
| 1707 { kForceValidateHeaders, LOAD_VALIDATE_CACHE }, | 1702 {kForceValidateHeaders, LOAD_VALIDATE_CACHE}, |
| 1708 }; | 1703 }; |
| 1709 | 1704 |
| 1710 bool range_found = false; | 1705 bool range_found = false; |
| 1711 bool external_validation_error = false; | 1706 bool external_validation_error = false; |
| 1712 | 1707 |
| 1713 if (request_->extra_headers.HasHeader(HttpRequestHeaders::kRange)) | 1708 if (request_->extra_headers.HasHeader(HttpRequestHeaders::kRange)) |
| 1714 range_found = true; | 1709 range_found = true; |
| 1715 | 1710 |
| 1716 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSpecialHeaders); ++i) { | 1711 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSpecialHeaders); ++i) { |
| 1717 if (HeaderMatches(request_->extra_headers, kSpecialHeaders[i].search)) { | 1712 if (HeaderMatches(request_->extra_headers, kSpecialHeaders[i].search)) { |
| 1718 effective_load_flags_ |= kSpecialHeaders[i].load_flag; | 1713 effective_load_flags_ |= kSpecialHeaders[i].load_flag; |
| 1719 break; | 1714 break; |
| 1720 } | 1715 } |
| 1721 } | 1716 } |
| 1722 | 1717 |
| 1723 // Check for conditionalization headers which may correspond with a | 1718 // Check for conditionalization headers which may correspond with a |
| 1724 // cache validation request. | 1719 // cache validation request. |
| 1725 for (size_t i = 0; i < arraysize(kValidationHeaders); ++i) { | 1720 for (size_t i = 0; i < arraysize(kValidationHeaders); ++i) { |
| 1726 const ValidationHeaderInfo& info = kValidationHeaders[i]; | 1721 const ValidationHeaderInfo& info = kValidationHeaders[i]; |
| 1727 std::string validation_value; | 1722 std::string validation_value; |
| 1728 if (request_->extra_headers.GetHeader( | 1723 if (request_->extra_headers.GetHeader(info.request_header_name, |
| 1729 info.request_header_name, &validation_value)) { | 1724 &validation_value)) { |
| 1730 if (!external_validation_.values[i].empty() || | 1725 if (!external_validation_.values[i].empty() || validation_value.empty()) { |
| 1731 validation_value.empty()) { | |
| 1732 external_validation_error = true; | 1726 external_validation_error = true; |
| 1733 } | 1727 } |
| 1734 external_validation_.values[i] = validation_value; | 1728 external_validation_.values[i] = validation_value; |
| 1735 external_validation_.initialized = true; | 1729 external_validation_.initialized = true; |
| 1736 } | 1730 } |
| 1737 } | 1731 } |
| 1738 | 1732 |
| 1739 // We don't support ranges and validation headers. | 1733 // We don't support ranges and validation headers. |
| 1740 if (range_found && external_validation_.initialized) { | 1734 if (range_found && external_validation_.initialized) { |
| 1741 LOG(WARNING) << "Byte ranges AND validation headers found."; | 1735 LOG(WARNING) << "Byte ranges AND validation headers found."; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1905 } | 1899 } |
| 1906 | 1900 |
| 1907 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; | 1901 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; |
| 1908 return OK; | 1902 return OK; |
| 1909 } | 1903 } |
| 1910 | 1904 |
| 1911 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() { | 1905 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() { |
| 1912 DCHECK_EQ(UPDATE, mode_); | 1906 DCHECK_EQ(UPDATE, mode_); |
| 1913 DCHECK(external_validation_.initialized); | 1907 DCHECK(external_validation_.initialized); |
| 1914 | 1908 |
| 1915 for (size_t i = 0; i < arraysize(kValidationHeaders); i++) { | 1909 for (size_t i = 0; i < arraysize(kValidationHeaders); i++) { |
| 1916 if (external_validation_.values[i].empty()) | 1910 if (external_validation_.values[i].empty()) |
| 1917 continue; | 1911 continue; |
| 1918 // Retrieve either the cached response's "etag" or "last-modified" header. | 1912 // Retrieve either the cached response's "etag" or "last-modified" header. |
| 1919 std::string validator; | 1913 std::string validator; |
| 1920 response_.headers->EnumerateHeader( | 1914 response_.headers->EnumerateHeader( |
| 1921 NULL, | 1915 NULL, kValidationHeaders[i].related_response_header_name, &validator); |
| 1922 kValidationHeaders[i].related_response_header_name, | |
| 1923 &validator); | |
| 1924 | 1916 |
| 1925 if (response_.headers->response_code() != 200 || truncated_ || | 1917 if (response_.headers->response_code() != 200 || truncated_ || |
| 1926 validator.empty() || validator != external_validation_.values[i]) { | 1918 validator.empty() || validator != external_validation_.values[i]) { |
| 1927 // The externally conditionalized request is not a validation request | 1919 // The externally conditionalized request is not a validation request |
| 1928 // for our existing cache entry. Proceed with caching disabled. | 1920 // for our existing cache entry. Proceed with caching disabled. |
| 1929 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1921 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 1930 DoneWritingToEntry(true); | 1922 DoneWritingToEntry(true); |
| 1931 } | 1923 } |
| 1932 } | 1924 } |
| 1933 | 1925 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2024 | 2016 |
| 2025 // Just use the first available ETag and/or Last-Modified header value. | 2017 // Just use the first available ETag and/or Last-Modified header value. |
| 2026 // TODO(darin): Or should we use the last? | 2018 // TODO(darin): Or should we use the last? |
| 2027 | 2019 |
| 2028 std::string etag_value; | 2020 std::string etag_value; |
| 2029 if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1)) | 2021 if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1)) |
| 2030 response_.headers->EnumerateHeader(NULL, "etag", &etag_value); | 2022 response_.headers->EnumerateHeader(NULL, "etag", &etag_value); |
| 2031 | 2023 |
| 2032 std::string last_modified_value; | 2024 std::string last_modified_value; |
| 2033 if (!vary_mismatch_) { | 2025 if (!vary_mismatch_) { |
| 2034 response_.headers->EnumerateHeader(NULL, "last-modified", | 2026 response_.headers->EnumerateHeader( |
| 2035 &last_modified_value); | 2027 NULL, "last-modified", &last_modified_value); |
| 2036 } | 2028 } |
| 2037 | 2029 |
| 2038 if (etag_value.empty() && last_modified_value.empty()) | 2030 if (etag_value.empty() && last_modified_value.empty()) |
| 2039 return false; | 2031 return false; |
| 2040 | 2032 |
| 2041 if (!partial_.get()) { | 2033 if (!partial_.get()) { |
| 2042 // Need to customize the request, so this forces us to allocate :( | 2034 // Need to customize the request, so this forces us to allocate :( |
| 2043 custom_request_.reset(new HttpRequestInfo(*request_)); | 2035 custom_request_.reset(new HttpRequestInfo(*request_)); |
| 2044 request_ = custom_request_.get(); | 2036 request_ = custom_request_.get(); |
| 2045 } | 2037 } |
| 2046 DCHECK(custom_request_.get()); | 2038 DCHECK(custom_request_.get()); |
| 2047 | 2039 |
| 2048 bool use_if_range = partial_.get() && !partial_->IsCurrentRangeCached() && | 2040 bool use_if_range = |
| 2049 !invalid_range_; | 2041 partial_.get() && !partial_->IsCurrentRangeCached() && !invalid_range_; |
| 2050 | 2042 |
| 2051 if (!etag_value.empty()) { | 2043 if (!etag_value.empty()) { |
| 2052 if (use_if_range) { | 2044 if (use_if_range) { |
| 2053 // We don't want to switch to WRITE mode if we don't have this block of a | 2045 // We don't want to switch to WRITE mode if we don't have this block of a |
| 2054 // byte-range request because we may have other parts cached. | 2046 // byte-range request because we may have other parts cached. |
| 2055 custom_request_->extra_headers.SetHeader( | 2047 custom_request_->extra_headers.SetHeader(HttpRequestHeaders::kIfRange, |
| 2056 HttpRequestHeaders::kIfRange, etag_value); | 2048 etag_value); |
| 2057 } else { | 2049 } else { |
| 2058 custom_request_->extra_headers.SetHeader( | 2050 custom_request_->extra_headers.SetHeader(HttpRequestHeaders::kIfNoneMatch, |
| 2059 HttpRequestHeaders::kIfNoneMatch, etag_value); | 2051 etag_value); |
| 2060 } | 2052 } |
| 2061 // For byte-range requests, make sure that we use only one way to validate | 2053 // For byte-range requests, make sure that we use only one way to validate |
| 2062 // the request. | 2054 // the request. |
| 2063 if (partial_.get() && !partial_->IsCurrentRangeCached()) | 2055 if (partial_.get() && !partial_->IsCurrentRangeCached()) |
| 2064 return true; | 2056 return true; |
| 2065 } | 2057 } |
| 2066 | 2058 |
| 2067 if (!last_modified_value.empty()) { | 2059 if (!last_modified_value.empty()) { |
| 2068 if (use_if_range) { | 2060 if (use_if_range) { |
| 2069 custom_request_->extra_headers.SetHeader( | 2061 custom_request_->extra_headers.SetHeader(HttpRequestHeaders::kIfRange, |
| 2070 HttpRequestHeaders::kIfRange, last_modified_value); | 2062 last_modified_value); |
| 2071 } else { | 2063 } else { |
| 2072 custom_request_->extra_headers.SetHeader( | 2064 custom_request_->extra_headers.SetHeader( |
| 2073 HttpRequestHeaders::kIfModifiedSince, last_modified_value); | 2065 HttpRequestHeaders::kIfModifiedSince, last_modified_value); |
| 2074 } | 2066 } |
| 2075 } | 2067 } |
| 2076 | 2068 |
| 2077 return true; | 2069 return true; |
| 2078 } | 2070 } |
| 2079 | 2071 |
| 2080 // We just received some headers from the server. We may have asked for a range, | 2072 // We just received some headers from the server. We may have asked for a range, |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2223 } | 2215 } |
| 2224 } | 2216 } |
| 2225 cache_->ConvertWriterToReader(entry_); | 2217 cache_->ConvertWriterToReader(entry_); |
| 2226 mode_ = READ; | 2218 mode_ = READ; |
| 2227 | 2219 |
| 2228 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 2220 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 2229 next_state_ = STATE_CACHE_READ_METADATA; | 2221 next_state_ = STATE_CACHE_READ_METADATA; |
| 2230 return OK; | 2222 return OK; |
| 2231 } | 2223 } |
| 2232 | 2224 |
| 2233 | |
| 2234 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { | 2225 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { |
| 2235 read_buf_ = data; | 2226 read_buf_ = data; |
| 2236 io_buf_len_ = data_len; | 2227 io_buf_len_ = data_len; |
| 2237 next_state_ = STATE_NETWORK_READ; | 2228 next_state_ = STATE_NETWORK_READ; |
| 2238 return DoLoop(OK); | 2229 return DoLoop(OK); |
| 2239 } | 2230 } |
| 2240 | 2231 |
| 2241 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) { | 2232 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) { |
| 2242 read_buf_ = data; | 2233 read_buf_ = data; |
| 2243 io_buf_len_ = data_len; | 2234 io_buf_len_ = data_len; |
| 2244 next_state_ = STATE_CACHE_READ_DATA; | 2235 next_state_ = STATE_CACHE_READ_DATA; |
| 2245 return DoLoop(OK); | 2236 return DoLoop(OK); |
| 2246 } | 2237 } |
| 2247 | 2238 |
| 2248 int HttpCache::Transaction::WriteToEntry(int index, int offset, | 2239 int HttpCache::Transaction::WriteToEntry(int index, |
| 2249 IOBuffer* data, int data_len, | 2240 int offset, |
| 2241 IOBuffer* data, |
| 2242 int data_len, |
| 2250 const CompletionCallback& callback) { | 2243 const CompletionCallback& callback) { |
| 2251 if (!entry_) | 2244 if (!entry_) |
| 2252 return data_len; | 2245 return data_len; |
| 2253 | 2246 |
| 2254 int rv = 0; | 2247 int rv = 0; |
| 2255 if (!partial_.get() || !data_len) { | 2248 if (!partial_.get() || !data_len) { |
| 2256 rv = entry_->disk_entry->WriteData(index, offset, data, data_len, callback, | 2249 rv = entry_->disk_entry->WriteData( |
| 2257 true); | 2250 index, offset, data, data_len, callback, true); |
| 2258 } else { | 2251 } else { |
| 2259 rv = partial_->CacheWrite(entry_->disk_entry, data, data_len, callback); | 2252 rv = partial_->CacheWrite(entry_->disk_entry, data, data_len, callback); |
| 2260 } | 2253 } |
| 2261 return rv; | 2254 return rv; |
| 2262 } | 2255 } |
| 2263 | 2256 |
| 2264 int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) { | 2257 int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) { |
| 2265 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; | 2258 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; |
| 2266 if (!entry_) | 2259 if (!entry_) |
| 2267 return OK; | 2260 return OK; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2289 bool skip_transient_headers = (cache_->mode() != RECORD); | 2282 bool skip_transient_headers = (cache_->mode() != RECORD); |
| 2290 | 2283 |
| 2291 if (truncated) | 2284 if (truncated) |
| 2292 DCHECK_EQ(200, response_.headers->response_code()); | 2285 DCHECK_EQ(200, response_.headers->response_code()); |
| 2293 | 2286 |
| 2294 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); | 2287 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); |
| 2295 response_.Persist(data->pickle(), skip_transient_headers, truncated); | 2288 response_.Persist(data->pickle(), skip_transient_headers, truncated); |
| 2296 data->Done(); | 2289 data->Done(); |
| 2297 | 2290 |
| 2298 io_buf_len_ = data->pickle()->size(); | 2291 io_buf_len_ = data->pickle()->size(); |
| 2299 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(), | 2292 return entry_->disk_entry->WriteData( |
| 2300 io_buf_len_, io_callback_, true); | 2293 kResponseInfoIndex, 0, data.get(), io_buf_len_, io_callback_, true); |
| 2301 } | 2294 } |
| 2302 | 2295 |
| 2303 int HttpCache::Transaction::AppendResponseDataToEntry( | 2296 int HttpCache::Transaction::AppendResponseDataToEntry( |
| 2304 IOBuffer* data, int data_len, const CompletionCallback& callback) { | 2297 IOBuffer* data, |
| 2298 int data_len, |
| 2299 const CompletionCallback& callback) { |
| 2305 if (!entry_ || !data_len) | 2300 if (!entry_ || !data_len) |
| 2306 return data_len; | 2301 return data_len; |
| 2307 | 2302 |
| 2308 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2303 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 2309 return WriteToEntry(kResponseContentIndex, current_size, data, data_len, | 2304 return WriteToEntry( |
| 2310 callback); | 2305 kResponseContentIndex, current_size, data, data_len, callback); |
| 2311 } | 2306 } |
| 2312 | 2307 |
| 2313 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2308 void HttpCache::Transaction::DoneWritingToEntry(bool success) { |
| 2314 if (!entry_) | 2309 if (!entry_) |
| 2315 return; | 2310 return; |
| 2316 | 2311 |
| 2317 RecordHistograms(); | 2312 RecordHistograms(); |
| 2318 | 2313 |
| 2319 cache_->DoneWritingToEntry(entry_, success); | 2314 cache_->DoneWritingToEntry(entry_, success); |
| 2320 entry_ = NULL; | 2315 entry_ = NULL; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2457 if (transaction_pattern_ == PATTERN_NOT_COVERED) | 2452 if (transaction_pattern_ == PATTERN_NOT_COVERED) |
| 2458 return; | 2453 return; |
| 2459 DCHECK(!range_requested_); | 2454 DCHECK(!range_requested_); |
| 2460 DCHECK(!first_cache_access_since_.is_null()); | 2455 DCHECK(!first_cache_access_since_.is_null()); |
| 2461 | 2456 |
| 2462 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; | 2457 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2463 | 2458 |
| 2464 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); | 2459 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2465 | 2460 |
| 2466 bool did_send_request = !send_request_since_.is_null(); | 2461 bool did_send_request = !send_request_since_.is_null(); |
| 2467 DCHECK( | 2462 DCHECK((did_send_request && |
| 2468 (did_send_request && | 2463 (transaction_pattern_ == PATTERN_ENTRY_NOT_CACHED || |
| 2469 (transaction_pattern_ == PATTERN_ENTRY_NOT_CACHED || | 2464 transaction_pattern_ == PATTERN_ENTRY_VALIDATED || |
| 2470 transaction_pattern_ == PATTERN_ENTRY_VALIDATED || | 2465 transaction_pattern_ == PATTERN_ENTRY_UPDATED || |
| 2471 transaction_pattern_ == PATTERN_ENTRY_UPDATED || | 2466 transaction_pattern_ == PATTERN_ENTRY_CANT_CONDITIONALIZE)) || |
| 2472 transaction_pattern_ == PATTERN_ENTRY_CANT_CONDITIONALIZE)) || | 2467 (!did_send_request && transaction_pattern_ == PATTERN_ENTRY_USED)); |
| 2473 (!did_send_request && transaction_pattern_ == PATTERN_ENTRY_USED)); | |
| 2474 | 2468 |
| 2475 if (!did_send_request) { | 2469 if (!did_send_request) { |
| 2476 DCHECK(transaction_pattern_ == PATTERN_ENTRY_USED); | 2470 DCHECK(transaction_pattern_ == PATTERN_ENTRY_USED); |
| 2477 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); | 2471 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); |
| 2478 return; | 2472 return; |
| 2479 } | 2473 } |
| 2480 | 2474 |
| 2481 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; | 2475 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; |
| 2482 int before_send_percent = | 2476 int before_send_percent = total_time.ToInternalValue() == 0 |
| 2483 total_time.ToInternalValue() == 0 ? 0 | 2477 ? 0 |
| 2484 : before_send_time * 100 / total_time; | 2478 : before_send_time * 100 / total_time; |
| 2485 DCHECK_LE(0, before_send_percent); | 2479 DCHECK_LE(0, before_send_percent); |
| 2486 DCHECK_GE(100, before_send_percent); | 2480 DCHECK_GE(100, before_send_percent); |
| 2487 | 2481 |
| 2488 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); | 2482 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); |
| 2489 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); | 2483 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); |
| 2490 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_percent); | 2484 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_percent); |
| 2491 | 2485 |
| 2492 // TODO(gavinp): Remove or minimize these histograms, particularly the ones | 2486 // TODO(gavinp): Remove or minimize these histograms, particularly the ones |
| 2493 // below this comment after we have received initial data. | 2487 // below this comment after we have received initial data. |
| 2494 switch (transaction_pattern_) { | 2488 switch (transaction_pattern_) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2520 default: | 2514 default: |
| 2521 NOTREACHED(); | 2515 NOTREACHED(); |
| 2522 } | 2516 } |
| 2523 } | 2517 } |
| 2524 | 2518 |
| 2525 void HttpCache::Transaction::OnIOComplete(int result) { | 2519 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2526 DoLoop(result); | 2520 DoLoop(result); |
| 2527 } | 2521 } |
| 2528 | 2522 |
| 2529 } // namespace net | 2523 } // namespace net |
| OLD | NEW |