Chromium Code Reviews| 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" // For OS_POSIX | 7 #include "build/build_config.h" // For OS_POSIX |
| 8 | 8 |
| 9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <limits> | |
| 14 #include <string> | 15 #include <string> |
| 16 #include <utility> | |
| 15 | 17 |
| 16 #include "base/bind.h" | 18 #include "base/bind.h" |
| 17 #include "base/callback_helpers.h" | 19 #include "base/callback_helpers.h" |
| 18 #include "base/compiler_specific.h" | 20 #include "base/compiler_specific.h" |
| 19 #include "base/format_macros.h" | 21 #include "base/format_macros.h" |
| 20 #include "base/location.h" | 22 #include "base/location.h" |
| 21 #include "base/macros.h" | 23 #include "base/macros.h" |
| 22 #include "base/metrics/histogram_macros.h" | 24 #include "base/metrics/histogram_macros.h" |
| 23 #include "base/metrics/sparse_histogram.h" | 25 #include "base/metrics/sparse_histogram.h" |
| 24 #include "base/single_thread_task_runner.h" | 26 #include "base/single_thread_task_runner.h" |
| 25 #include "base/strings/string_number_conversions.h" // For HexEncode. | 27 #include "base/strings/string_number_conversions.h" // For HexEncode. |
| 26 #include "base/strings/string_piece.h" | 28 #include "base/strings/string_piece.h" |
| 27 #include "base/strings/string_util.h" // For LowerCaseEqualsASCII. | 29 #include "base/strings/string_util.h" // For LowerCaseEqualsASCII. |
| 28 #include "base/strings/stringprintf.h" | 30 #include "base/strings/stringprintf.h" |
| 29 #include "base/threading/thread_task_runner_handle.h" | 31 #include "base/threading/thread_task_runner_handle.h" |
| 30 #include "base/time/clock.h" | 32 #include "base/time/clock.h" |
| 31 #include "base/trace_event/trace_event.h" | 33 #include "base/trace_event/trace_event.h" |
| 32 #include "base/values.h" | 34 #include "base/values.h" |
| 33 #include "net/base/auth.h" | 35 #include "net/base/auth.h" |
| 34 #include "net/base/load_flags.h" | 36 #include "net/base/load_flags.h" |
| 35 #include "net/base/load_timing_info.h" | 37 #include "net/base/load_timing_info.h" |
| 36 #include "net/base/trace_constants.h" | 38 #include "net/base/trace_constants.h" |
| 37 #include "net/base/upload_data_stream.h" | 39 #include "net/base/upload_data_stream.h" |
| 38 #include "net/cert/cert_status_flags.h" | 40 #include "net/cert/cert_status_flags.h" |
| 39 #include "net/cert/x509_certificate.h" | 41 #include "net/cert/x509_certificate.h" |
| 40 #include "net/disk_cache/disk_cache.h" | 42 #include "net/disk_cache/disk_cache.h" |
| 43 #include "net/http/http_cache_data_access.h" | |
| 44 #include "net/http/http_cache_shared_writers.h" | |
| 41 #include "net/http/http_network_session.h" | 45 #include "net/http/http_network_session.h" |
| 42 #include "net/http/http_request_info.h" | 46 #include "net/http/http_request_info.h" |
| 43 #include "net/http/http_util.h" | 47 #include "net/http/http_util.h" |
| 44 #include "net/log/net_log_event_type.h" | 48 #include "net/log/net_log_event_type.h" |
| 45 #include "net/ssl/ssl_cert_request_info.h" | 49 #include "net/ssl/ssl_cert_request_info.h" |
| 46 #include "net/ssl/ssl_config_service.h" | 50 #include "net/ssl/ssl_config_service.h" |
| 47 | 51 |
| 48 using base::Time; | 52 using base::Time; |
| 49 using base::TimeDelta; | 53 using base::TimeDelta; |
| 50 using base::TimeTicks; | 54 using base::TimeTicks; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 truncated_(false), | 178 truncated_(false), |
| 175 is_sparse_(false), | 179 is_sparse_(false), |
| 176 range_requested_(false), | 180 range_requested_(false), |
| 177 handling_206_(false), | 181 handling_206_(false), |
| 178 cache_pending_(false), | 182 cache_pending_(false), |
| 179 done_reading_(false), | 183 done_reading_(false), |
| 180 vary_mismatch_(false), | 184 vary_mismatch_(false), |
| 181 couldnt_conditionalize_request_(false), | 185 couldnt_conditionalize_request_(false), |
| 182 bypass_lock_for_test_(false), | 186 bypass_lock_for_test_(false), |
| 183 fail_conditionalization_for_test_(false), | 187 fail_conditionalization_for_test_(false), |
| 188 shared_(false), | |
| 189 initiate_shared_writing_(false), | |
| 190 shared_read_write_failure_result_(0), | |
| 184 io_buf_len_(0), | 191 io_buf_len_(0), |
| 185 read_offset_(0), | 192 read_offset_(0), |
| 186 effective_load_flags_(0), | 193 effective_load_flags_(0), |
| 187 write_len_(0), | 194 write_len_(0), |
| 188 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED), | 195 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED), |
| 189 validation_cause_(VALIDATION_CAUSE_UNDEFINED), | 196 validation_cause_(VALIDATION_CAUSE_UNDEFINED), |
| 190 total_received_bytes_(0), | 197 total_received_bytes_(0), |
| 191 total_sent_bytes_(0), | 198 total_sent_bytes_(0), |
| 192 websocket_handshake_stream_base_create_helper_(NULL), | 199 websocket_handshake_stream_base_create_helper_(NULL), |
| 200 have_full_request_headers_(false), | |
| 193 weak_factory_(this) { | 201 weak_factory_(this) { |
| 194 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction"); | 202 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction"); |
| 195 static_assert(HttpCache::Transaction::kNumValidationHeaders == | 203 static_assert(HttpCache::Transaction::kNumValidationHeaders == |
| 196 arraysize(kValidationHeaders), | 204 arraysize(kValidationHeaders), |
| 197 "invalid number of validation headers"); | 205 "invalid number of validation headers"); |
| 198 | 206 |
| 199 io_callback_ = base::Bind(&Transaction::OnIOComplete, | 207 io_callback_ = base::Bind(&Transaction::OnIOComplete, |
| 200 weak_factory_.GetWeakPtr()); | 208 weak_factory_.GetWeakPtr()); |
| 201 } | 209 } |
| 202 | 210 |
| 203 HttpCache::Transaction::~Transaction() { | 211 HttpCache::Transaction::~Transaction() { |
| 204 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); | 212 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); |
| 213 | |
| 214 if (shared_) { | |
| 215 // Remove transaction from shared writers and do any cleanup, if needed, for | |
| 216 // entry_->shared_writers and entry_. | |
| 217 RemoveTransactionFromSharedWriters(); | |
| 218 } | |
| 219 | |
| 205 // We may have to issue another IO, but we should never invoke the callback_ | 220 // We may have to issue another IO, but we should never invoke the callback_ |
| 206 // after this point. | 221 // after this point. |
| 207 callback_.Reset(); | 222 callback_.Reset(); |
| 208 | 223 |
| 209 if (cache_) { | 224 if (cache_) { |
| 210 if (entry_) { | 225 if (entry_) { |
| 211 bool cancel_request = reading_ && response_.headers.get(); | 226 bool cancel_request = reading_ && response_.headers.get(); |
| 212 if (cancel_request) { | 227 if (cancel_request) { |
| 213 if (partial_) { | 228 if (partial_) { |
| 214 entry_->disk_entry->CancelSparseIO(); | 229 entry_->disk_entry->CancelSparseIO(); |
| 215 } else { | 230 } else { |
| 216 cancel_request &= (response_.headers->response_code() == 200); | 231 cancel_request &= (response_.headers->response_code() == 200); |
| 217 } | 232 } |
| 218 } | 233 } |
| 219 | |
| 220 cache_->DoneWithEntry(entry_, this, cancel_request); | 234 cache_->DoneWithEntry(entry_, this, cancel_request); |
| 221 } else if (cache_pending_) { | 235 } else if (cache_pending_) { |
| 222 cache_->RemovePendingTransaction(this); | 236 cache_->RemovePendingTransaction(this); |
| 223 } | 237 } |
| 224 } | 238 } |
| 225 } | 239 } |
| 226 | 240 |
| 241 void HttpCache::Transaction::RemoveTransactionFromSharedWriters() { | |
| 242 // Current shared data_access_ consumer. | |
| 243 if (next_state_ == STATE_SHARED_NETWORK_READ_COMPLETE || | |
| 244 next_state_ == STATE_SHARED_CACHE_WRITE_DATA_COMPLETE) { | |
| 245 cache_->RemoveCurrentSharedWriter(this, entry_); | |
| 246 } else if (next_state_ == STATE_SHARED_NETWORK_READ_WAIT_COMPLETE) { | |
| 247 // Waiting on data_access_ operation to be completed by another | |
| 248 // transaction. | |
| 249 entry_->shared_writers->RemoveWaitingWriter(this); | |
| 250 } else if (next_state_ != STATE_NONE && | |
| 251 next_state_ <= STATE_ADD_TO_ENTRY_COMPLETE) { | |
| 252 // Pending transaction not yet to added to an entry. | |
| 253 cache_->RemovePendingTransaction(this); | |
| 254 // Set cache_pending_ to false so that more cleanup is not attempted in | |
| 255 // the destructor. | |
| 256 cache_pending_ = false; | |
| 257 } else if (validating_shared()) { | |
| 258 cache_->RemoveValidatingTransSharedWriters(this, entry_); | |
| 259 } else { | |
| 260 cache_->RemoveIdleSharedWriter(this, entry_); | |
| 261 } | |
| 262 | |
| 263 DCHECK(!shared_); | |
| 264 | |
| 265 // Since any cleanup needed in entry_ and shared_writers is already done, | |
| 266 // set entry_ to null. | |
| 267 entry_ = nullptr; | |
| 268 } | |
| 269 | |
| 227 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, | 270 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, |
| 228 const CompletionCallback& callback) { | 271 const CompletionCallback& callback) { |
| 229 DCHECK(buf); | 272 DCHECK(buf); |
| 230 DCHECK_GT(buf_len, 0); | 273 DCHECK_GT(buf_len, 0); |
| 231 DCHECK(!callback.is_null()); | 274 DCHECK(!callback.is_null()); |
| 232 if (!cache_.get() || !entry_) | 275 if (!cache_.get() || !entry_) |
| 233 return ERR_UNEXPECTED; | 276 return ERR_UNEXPECTED; |
| 234 | 277 |
| 235 // We don't need to track this operation for anything. | 278 // We don't need to track this operation for anything. |
| 236 // It could be possible to check if there is something already written and | 279 // It could be possible to check if there is something already written and |
| 237 // avoid writing again (it should be the same, right?), but let's allow the | 280 // avoid writing again (it should be the same, right?), but let's allow the |
| 238 // caller to "update" the contents with something new. | 281 // caller to "update" the contents with something new. |
| 239 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, | 282 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, |
| 240 callback, true); | 283 callback, true); |
| 241 } | 284 } |
| 242 | 285 |
| 243 bool HttpCache::Transaction::AddTruncatedFlag() { | 286 bool HttpCache::Transaction::AddTruncatedFlag() { |
| 244 DCHECK(mode_ & WRITE || mode_ == NONE); | 287 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 245 | 288 |
| 246 // Don't set the flag for sparse entries. | 289 // Don't set the flag for sparse entries. |
| 247 if (partial_ && !truncated_) | 290 if (partial_ && !truncated_) |
| 248 return true; | 291 return true; |
| 249 | 292 |
| 250 if (!CanResume(true)) | 293 if (!cache_->CanResumeEntry(true, request_->method, &response_, entry_)) |
| 251 return false; | 294 return false; |
| 252 | 295 |
| 253 // We may have received the whole resource already. | 296 // We may have received the whole resource already. |
| 254 if (done_reading_) | 297 if (done_reading_) |
| 255 return true; | 298 return true; |
| 256 | 299 |
| 257 truncated_ = true; | 300 truncated_ = true; |
| 258 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; | 301 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; |
| 259 DoLoop(OK); | 302 DoLoop(OK); |
| 260 return true; | 303 return true; |
| 261 } | 304 } |
| 262 | 305 |
| 263 LoadState HttpCache::Transaction::GetWriterLoadState() const { | 306 LoadState HttpCache::Transaction::GetWriterLoadState() const { |
| 264 if (network_trans_.get()) | 307 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 265 return network_trans_->GetLoadState(); | 308 if (network_transaction) |
| 309 return network_transaction->GetLoadState(); | |
| 266 if (entry_ || !request_) | 310 if (entry_ || !request_) |
| 267 return LOAD_STATE_IDLE; | 311 return LOAD_STATE_IDLE; |
| 268 return LOAD_STATE_WAITING_FOR_CACHE; | 312 return LOAD_STATE_WAITING_FOR_CACHE; |
| 269 } | 313 } |
| 270 | 314 |
| 271 const NetLogWithSource& HttpCache::Transaction::net_log() const { | 315 const NetLogWithSource& HttpCache::Transaction::net_log() const { |
| 272 return net_log_; | 316 return net_log_; |
| 273 } | 317 } |
| 274 | 318 |
| 275 int HttpCache::Transaction::Start(const HttpRequestInfo* request, | 319 int HttpCache::Transaction::Start(const HttpRequestInfo* request, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 } | 409 } |
| 366 | 410 |
| 367 bool HttpCache::Transaction::IsReadyToRestartForAuth() { | 411 bool HttpCache::Transaction::IsReadyToRestartForAuth() { |
| 368 if (!network_trans_.get()) | 412 if (!network_trans_.get()) |
| 369 return false; | 413 return false; |
| 370 return network_trans_->IsReadyToRestartForAuth(); | 414 return network_trans_->IsReadyToRestartForAuth(); |
| 371 } | 415 } |
| 372 | 416 |
| 373 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, | 417 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, |
| 374 const CompletionCallback& callback) { | 418 const CompletionCallback& callback) { |
| 419 if (next_state_ == STATE_SHARED_READ_WRITE_FAILED) { | |
| 420 if (net_log_.IsCapturing()) | |
| 421 net_log_.EndEventWithNetErrorCode( | |
| 422 NetLogEventType::HTTP_CACHE_SHARED_READ_WRITE_FAILED, | |
| 423 shared_read_write_failure_result_); | |
| 424 | |
| 425 return shared_read_write_failure_result_; | |
| 426 } | |
| 427 | |
| 375 DCHECK_EQ(next_state_, STATE_NONE); | 428 DCHECK_EQ(next_state_, STATE_NONE); |
| 376 DCHECK(buf); | 429 DCHECK(buf); |
| 377 DCHECK_GT(buf_len, 0); | 430 DCHECK_GT(buf_len, 0); |
| 378 DCHECK(!callback.is_null()); | 431 DCHECK(!callback.is_null()); |
| 379 | 432 |
| 380 DCHECK(callback_.is_null()); | 433 DCHECK(callback_.is_null()); |
| 381 | 434 |
| 382 if (!cache_.get()) | 435 if (!cache_.get()) |
| 383 return ERR_UNEXPECTED; | 436 return ERR_UNEXPECTED; |
| 384 | 437 |
| 385 // If we have an intermediate auth response at this point, then it means the | 438 // If we have an intermediate auth response at this point, then it means the |
| 386 // user wishes to read the network response (the error page). If there is a | 439 // user wishes to read the network response (the error page). If there is a |
| 387 // previous response in the cache then we should leave it intact. | 440 // previous response in the cache then we should leave it intact. |
| 388 if (auth_response_.headers.get() && mode_ != NONE) { | 441 if (auth_response_.headers.get() && mode_ != NONE) { |
| 389 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); | 442 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); |
| 390 DCHECK(mode_ & WRITE); | 443 DCHECK(mode_ & WRITE); |
| 391 DoneWritingToEntry(mode_ == READ_WRITE); | 444 DoneWritingToEntry(mode_ == READ_WRITE); |
| 392 mode_ = NONE; | 445 mode_ = NONE; |
| 393 } | 446 } |
| 394 | 447 |
| 395 reading_ = true; | 448 reading_ = true; |
| 396 read_buf_ = buf; | 449 read_buf_ = buf; |
| 397 io_buf_len_ = buf_len; | 450 io_buf_len_ = buf_len; |
| 398 if (network_trans_) { | 451 |
| 399 DCHECK(mode_ == WRITE || mode_ == NONE || | 452 if (shared_) { |
| 400 (mode_ == READ_WRITE && partial_)); | 453 int disk_entry_size = |
| 401 next_state_ = STATE_NETWORK_READ; | 454 entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 402 } else { | 455 if (read_offset_ == disk_entry_size) { |
| 403 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); | 456 next_state_ = STATE_SHARED_NETWORK_READ; |
| 404 next_state_ = STATE_CACHE_READ_DATA; | 457 } else { |
| 458 DCHECK_LT(read_offset_, disk_entry_size); | |
| 459 next_state_ = STATE_CACHE_READ_DATA; | |
| 460 } | |
| 461 } else { // not shared. | |
| 462 if (network_trans_ || data_access_) { | |
| 463 DCHECK(mode_ == WRITE || mode_ == NONE || | |
| 464 (mode_ == READ_WRITE && partial_)); | |
| 465 next_state_ = STATE_NETWORK_READ; | |
| 466 } else { // read-only | |
| 467 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); | |
| 468 next_state_ = STATE_CACHE_READ_DATA; | |
| 469 } | |
| 405 } | 470 } |
| 406 | 471 |
| 407 int rv = DoLoop(OK); | 472 int rv = DoLoop(OK); |
| 408 | 473 |
| 409 if (rv == ERR_IO_PENDING) { | 474 if (rv == ERR_IO_PENDING) { |
| 410 DCHECK(callback_.is_null()); | 475 DCHECK(callback_.is_null()); |
| 411 callback_ = callback; | 476 callback_ = callback; |
| 412 } | 477 } |
| 413 return rv; | 478 return rv; |
| 414 } | 479 } |
| 415 | 480 |
| 416 void HttpCache::Transaction::StopCaching() { | 481 void HttpCache::Transaction::StopCaching() { |
| 417 // We really don't know where we are now. Hopefully there is no operation in | 482 // We really don't know where we are now. Hopefully there is no operation in |
| 418 // progress, but nothing really prevents this method to be called after we | 483 // progress, but nothing really prevents this method to be called after we |
| 419 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this | 484 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this |
| 420 // point because we need the state machine for that (and even if we are really | 485 // point because we need the state machine for that (and even if we are really |
| 421 // free, that would be an asynchronous operation). In other words, keep the | 486 // free, that would be an asynchronous operation). In other words, keep the |
| 422 // entry how it is (it will be marked as truncated at destruction), and let | 487 // entry how it is (it will be marked as truncated at destruction), and let |
| 423 // the next piece of code that executes know that we are now reading directly | 488 // the next piece of code that executes know that we are now reading directly |
| 424 // from the net. | 489 // from the net. |
| 425 // TODO(mmenke): This doesn't release the lock on the cache entry, so a | 490 // TODO(mmenke): This doesn't release the lock on the cache entry, so a |
| 426 // future request for the resource will be blocked on this one. | 491 // future request for the resource will be blocked on this one. |
| 427 // Fix this. | 492 // Fix this. |
| 428 if (cache_.get() && entry_ && (mode_ & WRITE) && network_trans_.get() && | 493 if (shared_) { |
| 429 !is_sparse_ && !range_requested_) { | 494 // This might or might not stop caching based on whether other consumers |
| 495 // exist for this resource or not. If it does, shared_ will be set to false. | |
| 496 cache_->StopCachingSharedWriters(this, entry_); | |
|
Randy Smith (Not in Mondays)
2017/01/19 00:53:43
Why not delegate to entry_->shared_writers? That
shivanisha
2017/01/19 21:13:06
Going through HttpCache in this case basically ens
Randy Smith (Not in Mondays)
2017/01/20 19:54:31
Meaning that StopCachingSharedWriters() might dest
shivanisha
2017/01/25 19:46:13
Done. (Response in detail in the higher level feed
| |
| 497 } | |
| 498 if (!shared_ && cache_.get() && entry_ && (mode_ & WRITE) && | |
| 499 network_trans_.get() && !is_sparse_ && !range_requested_) { | |
| 430 mode_ = NONE; | 500 mode_ = NONE; |
| 431 } | 501 } |
| 432 } | 502 } |
| 433 | 503 |
| 434 bool HttpCache::Transaction::GetFullRequestHeaders( | 504 bool HttpCache::Transaction::GetFullRequestHeaders( |
| 435 HttpRequestHeaders* headers) const { | 505 HttpRequestHeaders* headers) const { |
| 436 if (network_trans_) | 506 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 437 return network_trans_->GetFullRequestHeaders(headers); | 507 if (network_transaction) { |
| 438 | 508 return network_transaction->GetFullRequestHeaders(headers); |
| 509 } else if (have_full_request_headers_) { | |
| 510 *headers = full_request_headers_; | |
| 511 return true; | |
| 512 } | |
| 439 // TODO(juliatuttle): Read headers from cache. | 513 // TODO(juliatuttle): Read headers from cache. |
| 440 return false; | 514 return false; |
| 441 } | 515 } |
| 442 | 516 |
| 443 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const { | 517 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const { |
| 444 int64_t total_received_bytes = total_received_bytes_; | 518 int64_t total_received_bytes = total_received_bytes_; |
| 445 if (network_trans_) | 519 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 446 total_received_bytes += network_trans_->GetTotalReceivedBytes(); | 520 if (network_transaction) |
| 521 total_received_bytes += network_transaction->GetTotalReceivedBytes(); | |
| 447 return total_received_bytes; | 522 return total_received_bytes; |
| 448 } | 523 } |
| 449 | 524 |
| 450 int64_t HttpCache::Transaction::GetTotalSentBytes() const { | 525 int64_t HttpCache::Transaction::GetTotalSentBytes() const { |
| 451 int64_t total_sent_bytes = total_sent_bytes_; | 526 int64_t total_sent_bytes = total_sent_bytes_; |
| 452 if (network_trans_) | 527 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 453 total_sent_bytes += network_trans_->GetTotalSentBytes(); | 528 if (network_transaction) |
| 529 total_sent_bytes += network_transaction->GetTotalSentBytes(); | |
| 454 return total_sent_bytes; | 530 return total_sent_bytes; |
| 455 } | 531 } |
| 456 | 532 |
| 457 void HttpCache::Transaction::DoneReading() { | 533 void HttpCache::Transaction::DoneReading() { |
| 458 if (cache_.get() && entry_) { | 534 if (cache_.get() && entry_) { |
| 459 DCHECK_NE(mode_, UPDATE); | 535 DCHECK_NE(mode_, UPDATE); |
| 536 bool perform_entry_cleanup = true; | |
| 537 if (shared_) { | |
| 538 cache_->DoneReadingSharedWriters(this, entry_); | |
| 539 | |
| 540 // shared_ should have been set to false. | |
| 541 DCHECK(!shared_); | |
| 542 | |
| 543 // entry_ cleanup already performed, if any. | |
| 544 perform_entry_cleanup = false; | |
| 545 } | |
| 546 | |
| 460 if (mode_ & WRITE) { | 547 if (mode_ & WRITE) { |
| 461 DoneWritingToEntry(true); | 548 DoneWritingToEntry(true, perform_entry_cleanup); |
| 462 } else if (mode_ & READ) { | 549 } else if (mode_ & READ) { |
| 463 // It is necessary to check mode_ & READ because it is possible | 550 // It is necessary to check mode_ & READ because it is possible |
| 464 // for mode_ to be NONE and entry_ non-NULL with a write entry | 551 // for mode_ to be NONE and entry_ non-NULL with a write entry |
| 465 // if StopCaching was called. | 552 // if StopCaching was called. |
| 466 cache_->DoneReadingFromEntry(entry_, this); | 553 cache_->DoneReadingFromEntry(entry_, this); |
| 467 entry_ = NULL; | 554 entry_ = NULL; |
| 468 } | 555 } |
| 469 } | 556 } |
| 470 } | 557 } |
| 471 | 558 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 490 return cache_->GetLoadStateForPendingTransaction(this); | 577 return cache_->GetLoadStateForPendingTransaction(this); |
| 491 | 578 |
| 492 return LOAD_STATE_IDLE; | 579 return LOAD_STATE_IDLE; |
| 493 } | 580 } |
| 494 | 581 |
| 495 void HttpCache::Transaction::SetQuicServerInfo( | 582 void HttpCache::Transaction::SetQuicServerInfo( |
| 496 QuicServerInfo* quic_server_info) {} | 583 QuicServerInfo* quic_server_info) {} |
| 497 | 584 |
| 498 bool HttpCache::Transaction::GetLoadTimingInfo( | 585 bool HttpCache::Transaction::GetLoadTimingInfo( |
| 499 LoadTimingInfo* load_timing_info) const { | 586 LoadTimingInfo* load_timing_info) const { |
| 500 if (network_trans_) | 587 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 501 return network_trans_->GetLoadTimingInfo(load_timing_info); | 588 if (network_transaction) |
| 589 return network_transaction->GetLoadTimingInfo(load_timing_info); | |
| 502 | 590 |
| 503 if (old_network_trans_load_timing_) { | 591 if (old_network_trans_load_timing_) { |
| 504 *load_timing_info = *old_network_trans_load_timing_; | 592 *load_timing_info = *old_network_trans_load_timing_; |
| 505 return true; | 593 return true; |
| 506 } | 594 } |
| 507 | 595 |
| 508 if (first_cache_access_since_.is_null()) | 596 if (first_cache_access_since_.is_null()) |
| 509 return false; | 597 return false; |
| 510 | 598 |
| 511 // If the cache entry was opened, return that time. | 599 // If the cache entry was opened, return that time. |
| 512 load_timing_info->send_start = first_cache_access_since_; | 600 load_timing_info->send_start = first_cache_access_since_; |
| 513 // This time doesn't make much sense when reading from the cache, so just use | 601 // This time doesn't make much sense when reading from the cache, so just use |
| 514 // the same time as send_start. | 602 // the same time as send_start. |
| 515 load_timing_info->send_end = first_cache_access_since_; | 603 load_timing_info->send_end = first_cache_access_since_; |
| 516 return true; | 604 return true; |
| 517 } | 605 } |
| 518 | 606 |
| 519 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { | 607 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { |
| 520 if (network_trans_) | 608 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 521 return network_trans_->GetRemoteEndpoint(endpoint); | 609 if (network_transaction) |
| 610 return network_transaction->GetRemoteEndpoint(endpoint); | |
| 522 | 611 |
| 523 if (!old_remote_endpoint_.address().empty()) { | 612 if (!old_remote_endpoint_.address().empty()) { |
| 524 *endpoint = old_remote_endpoint_; | 613 *endpoint = old_remote_endpoint_; |
| 525 return true; | 614 return true; |
| 526 } | 615 } |
| 527 | 616 |
| 528 return false; | 617 return false; |
| 529 } | 618 } |
| 530 | 619 |
| 531 void HttpCache::Transaction::PopulateNetErrorDetails( | 620 void HttpCache::Transaction::PopulateNetErrorDetails( |
| 532 NetErrorDetails* details) const { | 621 NetErrorDetails* details) const { |
| 533 if (network_trans_) | 622 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 534 return network_trans_->PopulateNetErrorDetails(details); | 623 if (network_transaction) |
| 624 network_transaction->PopulateNetErrorDetails(details); | |
| 535 return; | 625 return; |
| 536 } | 626 } |
| 537 | 627 |
| 538 void HttpCache::Transaction::SetPriority(RequestPriority priority) { | 628 void HttpCache::Transaction::SetPriority(RequestPriority priority) { |
| 539 priority_ = priority; | 629 priority_ = priority; |
| 540 if (network_trans_) | 630 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 541 network_trans_->SetPriority(priority_); | 631 if (network_transaction) |
| 632 network_transaction->SetPriority(priority_); | |
| 542 } | 633 } |
| 543 | 634 |
| 544 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( | 635 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( |
| 545 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { | 636 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { |
| 546 websocket_handshake_stream_base_create_helper_ = create_helper; | 637 websocket_handshake_stream_base_create_helper_ = create_helper; |
| 547 if (network_trans_) | 638 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 548 network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper); | 639 if (network_transaction) |
| 640 network_transaction->SetWebSocketHandshakeStreamCreateHelper(create_helper); | |
| 549 } | 641 } |
| 550 | 642 |
| 551 void HttpCache::Transaction::SetBeforeNetworkStartCallback( | 643 void HttpCache::Transaction::SetBeforeNetworkStartCallback( |
| 552 const BeforeNetworkStartCallback& callback) { | 644 const BeforeNetworkStartCallback& callback) { |
| 553 DCHECK(!network_trans_); | 645 DCHECK(!network_trans_); |
| 554 before_network_start_callback_ = callback; | 646 before_network_start_callback_ = callback; |
| 555 } | 647 } |
| 556 | 648 |
| 557 void HttpCache::Transaction::SetBeforeHeadersSentCallback( | 649 void HttpCache::Transaction::SetBeforeHeadersSentCallback( |
| 558 const BeforeHeadersSentCallback& callback) { | 650 const BeforeHeadersSentCallback& callback) { |
| 559 DCHECK(!network_trans_); | 651 DCHECK(!network_trans_); |
| 560 before_headers_sent_callback_ = callback; | 652 before_headers_sent_callback_ = callback; |
| 561 } | 653 } |
| 562 | 654 |
| 563 int HttpCache::Transaction::ResumeNetworkStart() { | 655 int HttpCache::Transaction::ResumeNetworkStart() { |
| 564 if (network_trans_) | 656 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 565 return network_trans_->ResumeNetworkStart(); | 657 if (network_transaction) |
| 658 network_transaction->ResumeNetworkStart(); | |
| 566 return ERR_UNEXPECTED; | 659 return ERR_UNEXPECTED; |
| 567 } | 660 } |
| 568 | 661 |
| 569 void HttpCache::Transaction::GetConnectionAttempts( | 662 void HttpCache::Transaction::GetConnectionAttempts( |
| 570 ConnectionAttempts* out) const { | 663 ConnectionAttempts* out) const { |
| 571 ConnectionAttempts new_connection_attempts; | 664 ConnectionAttempts new_connection_attempts; |
| 572 if (network_trans_) | 665 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 573 network_trans_->GetConnectionAttempts(&new_connection_attempts); | 666 if (network_transaction) |
| 667 network_transaction->GetConnectionAttempts(&new_connection_attempts); | |
| 574 | 668 |
| 575 out->swap(new_connection_attempts); | 669 out->swap(new_connection_attempts); |
| 576 out->insert(out->begin(), old_connection_attempts_.begin(), | 670 out->insert(out->begin(), old_connection_attempts_.begin(), |
| 577 old_connection_attempts_.end()); | 671 old_connection_attempts_.end()); |
| 578 } | 672 } |
| 579 | 673 |
| 580 //----------------------------------------------------------------------------- | 674 //----------------------------------------------------------------------------- |
| 581 | 675 |
| 582 // A few common patterns: (Foo* means Foo -> FooComplete) | 676 // A few common patterns: (Foo* means Foo -> FooComplete) |
| 583 // | 677 // |
| 584 // 1. Not-cached entry: | 678 // 1. Not-cached entry: |
| 585 // Start(): | 679 // Start(): |
| 586 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> | 680 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> |
| 587 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> | 681 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> |
| 588 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> | 682 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> |
| 589 // PartialHeadersReceived | 683 // PartialHeadersReceived |
| 590 // | 684 // |
| 591 // Read(): | 685 // Read(): (For transactions that are not eligible for shared writing) |
| 592 // NetworkRead* -> CacheWriteData* | 686 // NetworkRead* -> CacheWriteData* |
| 593 // | 687 // |
| 688 // Read(): (For transactions that are eligible for shared writing) | |
| 689 // SharedNetworkRead* -> SharedCacheWriteData* | |
| 690 // | |
| 691 // Read(): (For a transaction that is shared and another read is already in | |
| 692 // progress) | |
| 693 // SharedNetworkRead -> SharedNetworkReadWaitComplete | |
| 694 // | |
| 594 // 2. Cached entry, no validation: | 695 // 2. Cached entry, no validation: |
| 595 // Start(): | 696 // Start(): |
| 596 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 697 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 597 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 698 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 598 // BeginCacheValidation() -> SetupEntryForRead() | 699 // BeginCacheValidation() -> SetupEntryForRead() |
| 599 // | 700 // |
| 600 // Read(): | 701 // Read(): (When response is already written to the cache.) |
| 601 // CacheReadData* | 702 // CacheReadData* |
| 602 // | 703 // |
| 704 // Read(): (When response is currently being written to the cache by shared | |
| 705 // writing.) | |
| 706 // SharedNetworkRead* -> SharedCacheWriteData* | |
| 707 // | |
| 603 // 3. Cached entry, validation (304): | 708 // 3. Cached entry, validation (304): |
| 604 // Start(): | 709 // Start(): |
| 605 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 710 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 606 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 711 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 607 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 712 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 608 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> | 713 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> |
| 609 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> | 714 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> |
| 610 // PartialHeadersReceived | 715 // PartialHeadersReceived |
| 611 // | 716 // |
| 612 // Read(): | 717 // Read(): () (When response is already written to the cache.) |
| 613 // CacheReadData* | 718 // CacheReadData* |
| 614 // | 719 // |
| 720 // Read(): (When response is currently being written to the cache by shared | |
| 721 // writing.) | |
| 722 // SharedNetworkRead* -> SharedCacheWriteData* | |
| 723 // | |
| 615 // 4. Cached entry, validation and replace (200): | 724 // 4. Cached entry, validation and replace (200): |
| 616 // Start(): | 725 // Start(): |
| 617 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 726 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 618 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 727 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 619 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 728 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 620 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> | 729 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> |
| 621 // TruncateCachedMetadata* -> PartialHeadersReceived | 730 // TruncateCachedMetadata* -> PartialHeadersReceived |
| 622 // | 731 // |
| 623 // Read(): | 732 // Read(): |
| 624 // NetworkRead* -> CacheWriteData* | 733 // NetworkRead* -> CacheWriteData* |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> | 808 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> |
| 700 // BeginPartialCacheValidation() -> BeginCacheValidation() -> | 809 // BeginPartialCacheValidation() -> BeginCacheValidation() -> |
| 701 // SetupEntryForRead() | 810 // SetupEntryForRead() |
| 702 // | 811 // |
| 703 // Read(): | 812 // Read(): |
| 704 // CacheReadData* | 813 // CacheReadData* |
| 705 // | 814 // |
| 706 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: | 815 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: |
| 707 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between | 816 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between |
| 708 // CacheReadResponse* and CacheDispatchValidation. | 817 // CacheReadResponse* and CacheDispatchValidation. |
| 818 // | |
| 709 int HttpCache::Transaction::DoLoop(int result) { | 819 int HttpCache::Transaction::DoLoop(int result) { |
| 710 DCHECK(next_state_ != STATE_NONE); | 820 DCHECK(next_state_ != STATE_NONE); |
| 711 | 821 |
| 712 int rv = result; | 822 int rv = result; |
| 713 do { | 823 do { |
| 714 State state = next_state_; | 824 State state = next_state_; |
| 715 next_state_ = STATE_NONE; | 825 next_state_ = STATE_NONE; |
| 716 switch (state) { | 826 switch (state) { |
| 717 case STATE_GET_BACKEND: | 827 case STATE_GET_BACKEND: |
| 718 DCHECK_EQ(OK, rv); | 828 DCHECK_EQ(OK, rv); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 case STATE_CACHE_WRITE_DATA_COMPLETE: | 976 case STATE_CACHE_WRITE_DATA_COMPLETE: |
| 867 rv = DoCacheWriteDataComplete(rv); | 977 rv = DoCacheWriteDataComplete(rv); |
| 868 break; | 978 break; |
| 869 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: | 979 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: |
| 870 DCHECK_EQ(OK, rv); | 980 DCHECK_EQ(OK, rv); |
| 871 rv = DoCacheWriteTruncatedResponse(); | 981 rv = DoCacheWriteTruncatedResponse(); |
| 872 break; | 982 break; |
| 873 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: | 983 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: |
| 874 rv = DoCacheWriteTruncatedResponseComplete(rv); | 984 rv = DoCacheWriteTruncatedResponseComplete(rv); |
| 875 break; | 985 break; |
| 986 case STATE_SHARED_NETWORK_READ: | |
| 987 DCHECK_EQ(OK, rv); | |
| 988 rv = DoSharedNetworkRead(); | |
| 989 break; | |
| 990 case STATE_SHARED_NETWORK_READ_COMPLETE: | |
| 991 rv = DoSharedNetworkReadComplete(rv); | |
| 992 break; | |
| 993 case STATE_SHARED_NETWORK_READ_WAIT_COMPLETE: | |
| 994 rv = DoSharedNetworkReadWaitComplete(rv); | |
| 995 break; | |
| 996 case STATE_SHARED_CACHE_WRITE_DATA: | |
| 997 rv = DoSharedCacheWriteData(rv); | |
| 998 break; | |
| 999 case STATE_SHARED_CACHE_WRITE_DATA_COMPLETE: | |
| 1000 rv = DoSharedCacheWriteDataComplete(rv); | |
| 1001 break; | |
| 1002 case STATE_SHARED_READ_WRITE_FAILED: | |
| 1003 rv = DoSharedReadWriteFailed(); | |
| 1004 break; | |
| 876 default: | 1005 default: |
| 877 NOTREACHED() << "bad state"; | 1006 NOTREACHED() << "bad state"; |
| 878 rv = ERR_FAILED; | 1007 rv = ERR_FAILED; |
| 879 break; | 1008 break; |
| 880 } | 1009 } |
| 881 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 1010 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| 882 | 1011 |
| 883 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 1012 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 884 read_buf_ = NULL; // Release the buffer before invoking the callback. | 1013 read_buf_ = NULL; // Release the buffer before invoking the callback. |
| 885 base::ResetAndReturn(&callback_).Run(rv); | 1014 base::ResetAndReturn(&callback_).Run(rv); |
| (...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1503 | 1632 |
| 1504 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); | 1633 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); |
| 1505 | 1634 |
| 1506 if (new_response_->headers->response_code() == 416 && | 1635 if (new_response_->headers->response_code() == 416 && |
| 1507 (request_->method == "GET" || request_->method == "POST")) { | 1636 (request_->method == "GET" || request_->method == "POST")) { |
| 1508 // If there is an active entry it may be destroyed with this transaction. | 1637 // If there is an active entry it may be destroyed with this transaction. |
| 1509 SetResponse(*new_response_); | 1638 SetResponse(*new_response_); |
| 1510 return OK; | 1639 return OK; |
| 1511 } | 1640 } |
| 1512 | 1641 |
| 1642 // If the transaction is shared and it is a 200 or an error response, then | |
| 1643 // doom the entry and let this transaction continue without writing to the | |
| 1644 // cache if shared writers contain more transactions. If not, continue | |
| 1645 // writing to the cache and also transfer the network transaction to shared | |
| 1646 // writers. | |
| 1647 if (shared_ && new_response->headers->response_code() != 304) { | |
| 1648 network_trans_ = cache_->ValidationNoMatchSharedWriters( | |
| 1649 cache_key_, this, std::move(network_trans_), priority_, entry_); | |
| 1650 if (!shared_) { | |
| 1651 DCHECK(network_trans_); | |
| 1652 if (cache_entry_status_ == CacheEntryStatus::ENTRY_UNDEFINED) { | |
| 1653 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING); | |
| 1654 } | |
| 1655 DoneWritingToEntry(false, false); | |
| 1656 return OK; | |
| 1657 } else { | |
| 1658 DCHECK(!network_trans_); | |
| 1659 } | |
| 1660 } | |
| 1661 | |
| 1513 // Are we expecting a response to a conditional query? | 1662 // Are we expecting a response to a conditional query? |
| 1514 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 1663 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
| 1515 if (new_response->headers->response_code() == 304 || handling_206_) { | 1664 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 1516 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); | 1665 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); |
| 1517 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 1666 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
| 1518 return OK; | 1667 return OK; |
| 1519 } | 1668 } |
| 1520 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); | 1669 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); |
| 1521 mode_ = WRITE; | 1670 mode_ = WRITE; |
| 1522 } | 1671 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1625 SetResponse(*new_response_); | 1774 SetResponse(*new_response_); |
| 1626 | 1775 |
| 1627 if (request_->method == "HEAD") { | 1776 if (request_->method == "HEAD") { |
| 1628 // This response is replacing the cached one. | 1777 // This response is replacing the cached one. |
| 1629 DoneWritingToEntry(false); | 1778 DoneWritingToEntry(false); |
| 1630 mode_ = NONE; | 1779 mode_ = NONE; |
| 1631 new_response_ = NULL; | 1780 new_response_ = NULL; |
| 1632 return OK; | 1781 return OK; |
| 1633 } | 1782 } |
| 1634 | 1783 |
| 1635 if (handling_206_ && !CanResume(false)) { | 1784 if (handling_206_ && |
| 1785 !cache_->CanResumeEntry(false, request_->method, &response_, entry_)) { | |
| 1636 // There is no point in storing this resource because it will never be used. | 1786 // There is no point in storing this resource because it will never be used. |
| 1637 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. | 1787 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. |
| 1638 DoneWritingToEntry(false); | 1788 DoneWritingToEntry(false); |
| 1639 if (partial_) | 1789 if (partial_) |
| 1640 partial_->FixResponseHeaders(response_.headers.get(), true); | 1790 partial_->FixResponseHeaders(response_.headers.get(), true); |
| 1641 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1791 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1642 return OK; | 1792 return OK; |
| 1643 } | 1793 } |
| 1644 | 1794 |
| 1645 next_state_ = STATE_CACHE_WRITE_RESPONSE; | 1795 next_state_ = STATE_CACHE_WRITE_RESPONSE; |
| 1646 return OK; | 1796 return OK; |
| 1647 } | 1797 } |
| 1648 | 1798 |
| 1649 int HttpCache::Transaction::DoCacheWriteResponse() { | 1799 int HttpCache::Transaction::DoCacheWriteResponse() { |
| 1650 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); | 1800 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); |
| 1651 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; | 1801 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; |
| 1652 return WriteResponseInfoToEntry(truncated_); | 1802 return WriteResponseInfoToEntry(truncated_); |
| 1653 } | 1803 } |
| 1654 | 1804 |
| 1655 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { | 1805 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { |
| 1656 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); | 1806 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); |
| 1657 next_state_ = STATE_TRUNCATE_CACHED_DATA; | 1807 next_state_ = STATE_TRUNCATE_CACHED_DATA; |
| 1658 return OnWriteResponseInfoToEntryComplete(result); | 1808 return OnWriteResponseInfoToEntryComplete(result); |
| 1659 } | 1809 } |
| 1660 | 1810 |
| 1811 void HttpCache::Transaction::ResetShared(bool continue_network_reading, | |
| 1812 bool continue_cache_reading) { | |
| 1813 if (!continue_network_reading) { | |
| 1814 SaveSharedNetworkTransactionInfo(); | |
| 1815 } | |
| 1816 if (continue_cache_reading) { | |
| 1817 mode_ = READ; | |
| 1818 } | |
| 1819 shared_ = false; | |
| 1820 } | |
| 1821 | |
| 1822 void HttpCache::Transaction::SetShared() { | |
| 1823 shared_ = true; | |
| 1824 } | |
| 1825 | |
| 1826 bool HttpCache::Transaction::validating_shared() const { | |
| 1827 return shared_ && next_state_ != STATE_NONE && | |
| 1828 next_state_ <= STATE_START_STATE_MACHINE_FINAL; | |
| 1829 } | |
| 1830 | |
| 1661 int HttpCache::Transaction::DoTruncateCachedData() { | 1831 int HttpCache::Transaction::DoTruncateCachedData() { |
| 1662 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); | 1832 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); |
| 1663 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; | 1833 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; |
| 1664 if (!entry_) | 1834 if (!entry_) |
| 1665 return OK; | 1835 return OK; |
| 1666 if (net_log_.IsCapturing()) | 1836 if (net_log_.IsCapturing()) |
| 1667 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); | 1837 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); |
| 1668 // Truncate the stream. | 1838 // Truncate the stream. |
| 1669 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); | 1839 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); |
| 1670 } | 1840 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1699 if (net_log_.IsCapturing()) { | 1869 if (net_log_.IsCapturing()) { |
| 1700 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, | 1870 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, |
| 1701 result); | 1871 result); |
| 1702 } | 1872 } |
| 1703 } | 1873 } |
| 1704 | 1874 |
| 1705 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1875 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1706 return OK; | 1876 return OK; |
| 1707 } | 1877 } |
| 1708 | 1878 |
| 1879 void HttpCache::Transaction::ProcessForSharedWriting() { | |
| 1880 // Should not be already reading. | |
| 1881 if (reading_) | |
| 1882 return; | |
| 1883 | |
| 1884 // If not already part of SharedWriters, then check if one should be | |
| 1885 // created. | |
| 1886 if (!shared_ && !IsEligibleForSharedWriting()) | |
| 1887 return; | |
| 1888 | |
| 1889 if (shared_) { | |
| 1890 // Non 304 case is already handled in DoSuccessfulSendRequest. | |
| 1891 if (response_.headers->response_code() != 304) { | |
| 1892 return; | |
| 1893 } | |
| 1894 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING); | |
| 1895 entry_->shared_writers->OnValidationMatch(this, priority_); | |
| 1896 network_trans_.reset(); | |
| 1897 return; | |
| 1898 } | |
| 1899 | |
| 1900 // Do not create a SharedWriters if its a Redirect response. | |
| 1901 if (response_.headers->response_code() != 200) | |
| 1902 return; | |
| 1903 | |
| 1904 // or if its a no-store response. | |
| 1905 if (!entry_) | |
| 1906 return; | |
| 1907 | |
| 1908 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || | |
| 1909 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || | |
| 1910 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE || | |
| 1911 cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER); | |
| 1912 // Measure how many requests out of the total of "not cached" and "updated" | |
| 1913 // are initiating Shared Writing. | |
| 1914 initiate_shared_writing_ = true; | |
| 1915 DCHECK(entry_ && network_trans_); | |
| 1916 cache_->CreateSharedWriters(this, std::move(network_trans_), priority_); | |
| 1917 } | |
| 1918 | |
| 1709 int HttpCache::Transaction::DoPartialHeadersReceived() { | 1919 int HttpCache::Transaction::DoPartialHeadersReceived() { |
| 1710 new_response_ = NULL; | 1920 new_response_ = NULL; |
| 1711 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1921 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 1712 next_state_ = STATE_CACHE_READ_METADATA; | 1922 next_state_ = STATE_CACHE_READ_METADATA; |
| 1713 | 1923 |
| 1924 ProcessForSharedWriting(); | |
| 1925 | |
| 1714 if (!partial_) | 1926 if (!partial_) |
| 1715 return OK; | 1927 return OK; |
| 1716 | 1928 |
| 1717 if (reading_) { | 1929 if (reading_) { |
| 1718 if (network_trans_.get()) { | 1930 if (network_trans_.get()) { |
| 1719 next_state_ = STATE_NETWORK_READ; | 1931 next_state_ = STATE_NETWORK_READ; |
| 1720 } else { | 1932 } else { |
| 1721 next_state_ = STATE_CACHE_READ_DATA; | 1933 next_state_ = STATE_CACHE_READ_DATA; |
| 1722 } | 1934 } |
| 1723 } else if (mode_ != NONE) { | 1935 } else if (mode_ != NONE) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1749 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, | 1961 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, |
| 1750 result); | 1962 result); |
| 1751 if (result != response_.metadata->size()) | 1963 if (result != response_.metadata->size()) |
| 1752 return OnCacheReadError(result, false); | 1964 return OnCacheReadError(result, false); |
| 1753 return OK; | 1965 return OK; |
| 1754 } | 1966 } |
| 1755 | 1967 |
| 1756 int HttpCache::Transaction::DoNetworkRead() { | 1968 int HttpCache::Transaction::DoNetworkRead() { |
| 1757 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); | 1969 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); |
| 1758 next_state_ = STATE_NETWORK_READ_COMPLETE; | 1970 next_state_ = STATE_NETWORK_READ_COMPLETE; |
| 1759 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); | 1971 if (!data_access_) { |
| 1972 DCHECK(network_trans_); | |
| 1973 // Create a DataAccess object if not already done. | |
| 1974 data_access_ = | |
| 1975 base::MakeUnique<DataAccess>(std::move(network_trans_), entry_); | |
| 1976 } | |
| 1977 return data_access_->Read(read_buf_, io_buf_len_, io_callback_); | |
| 1760 } | 1978 } |
| 1761 | 1979 |
| 1762 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 1980 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| 1763 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); | 1981 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); |
| 1982 if (net_log_.IsCapturing()) | |
| 1983 net_log_.EndEventWithNetErrorCode( | |
| 1984 NetLogEventType::HTTP_CACHE_NETWORK_READ_COMPLETE, result); | |
| 1985 | |
| 1764 DCHECK(mode_ & WRITE || mode_ == NONE); | 1986 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 1765 | 1987 |
| 1766 if (!cache_.get()) | 1988 if (!cache_.get()) |
| 1767 return ERR_UNEXPECTED; | 1989 return ERR_UNEXPECTED; |
| 1768 | 1990 |
| 1769 // If there is an error or we aren't saving the data, we are done; just wait | 1991 // If there is an error or we aren't saving the data, we are done; just wait |
| 1770 // until the destructor runs to see if we can keep the data. | 1992 // until the destructor runs to see if we can keep the data. |
| 1771 if (mode_ == NONE || result < 0) | 1993 if (mode_ == NONE || result < 0) |
| 1772 return result; | 1994 return result; |
| 1773 | 1995 |
| 1774 next_state_ = STATE_CACHE_WRITE_DATA; | 1996 next_state_ = STATE_CACHE_WRITE_DATA; |
| 1775 return result; | 1997 return result; |
| 1776 } | 1998 } |
| 1777 | 1999 |
| 2000 int HttpCache::Transaction::DoSharedNetworkRead() { | |
| 2001 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkRead"); | |
| 2002 if (net_log_.IsCapturing()) | |
| 2003 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ); | |
| 2004 | |
| 2005 next_state_ = STATE_SHARED_NETWORK_READ_COMPLETE; | |
| 2006 bool shared_read_in_progress = false; | |
| 2007 int result = entry_->shared_writers->Read( | |
| 2008 read_buf_, io_buf_len_, io_callback_, this, &shared_read_in_progress); | |
| 2009 if (shared_read_in_progress) { | |
| 2010 next_state_ = STATE_SHARED_NETWORK_READ_WAIT_COMPLETE; | |
| 2011 } | |
| 2012 return result; | |
| 2013 } | |
| 2014 | |
| 2015 int HttpCache::Transaction::DoSharedNetworkReadComplete(int result) { | |
| 2016 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadComplete"); | |
| 2017 if (net_log_.IsCapturing()) | |
| 2018 net_log_.EndEventWithNetErrorCode( | |
| 2019 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_COMPLETE, result); | |
| 2020 | |
| 2021 if (result <= 0) { | |
| 2022 // Set entry as null so that the destructor does not invoke DoneWithEntry | |
| 2023 // again as entry_ is already cleaned up by SharedWriters. | |
| 2024 entry_ = nullptr; | |
| 2025 return result; | |
| 2026 } | |
| 2027 | |
| 2028 read_offset_ += result; | |
| 2029 | |
| 2030 next_state_ = STATE_SHARED_CACHE_WRITE_DATA; | |
| 2031 return result; | |
| 2032 } | |
| 2033 | |
| 2034 int HttpCache::Transaction::DoSharedCacheWriteData(int result) { | |
| 2035 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteData"); | |
| 2036 if (net_log_.IsCapturing()) | |
| 2037 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA); | |
| 2038 | |
| 2039 next_state_ = STATE_SHARED_CACHE_WRITE_DATA_COMPLETE; | |
| 2040 write_len_ = result; | |
| 2041 return entry_->shared_writers->CacheWrite(read_buf_, write_len_, io_callback_, | |
| 2042 this); | |
| 2043 } | |
| 2044 | |
| 2045 int HttpCache::Transaction::DoSharedCacheWriteDataComplete(int result) { | |
| 2046 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteDataComplete"); | |
| 2047 if (net_log_.IsCapturing()) | |
| 2048 net_log_.EndEventWithNetErrorCode( | |
| 2049 NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA_COMPLETE, result); | |
| 2050 | |
| 2051 if (result != write_len_) { | |
| 2052 DoneWritingToEntry(false, false); | |
| 2053 // Consumer need not know that it was a failure since this transaction can | |
| 2054 // continue reading from the network. | |
| 2055 result = write_len_; | |
| 2056 } else { | |
| 2057 done_reading_ = cache_->IsResponseCompleted(entry_, &response_); | |
| 2058 if (result == 0) { | |
| 2059 DoneWritingToEntry(true, false); | |
| 2060 } | |
| 2061 } | |
| 2062 return result; | |
| 2063 } | |
| 2064 | |
| 2065 int HttpCache::Transaction::DoSharedNetworkReadWaitComplete(int result) { | |
| 2066 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadWaitComplete"); | |
| 2067 if (net_log_.IsCapturing()) | |
| 2068 net_log_.EndEventWithNetErrorCode( | |
| 2069 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_WAIT_COMPLETE, result); | |
| 2070 | |
| 2071 // If its a network read failure or cache write failure, we just return the | |
| 2072 // result. | |
| 2073 // If its a cache write success, read_buf_ would have been filled | |
| 2074 // with the read data by SharedWriters. | |
| 2075 if (result == 0) { // response is complete. | |
| 2076 DoneWritingToEntry(true, false); // changes the mode_ to NONE. | |
| 2077 } else if (result > 0) { | |
| 2078 read_offset_ += result; | |
| 2079 } else { | |
| 2080 // Set entry as null so that the destructor does not invoke DoneWithEntry | |
| 2081 // again as entry_ is already cleaned up by SharedWriters. | |
| 2082 entry_ = nullptr; | |
| 2083 } | |
| 2084 | |
| 2085 return result; | |
| 2086 } | |
| 2087 | |
| 1778 int HttpCache::Transaction::DoCacheReadData() { | 2088 int HttpCache::Transaction::DoCacheReadData() { |
| 1779 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); | 2089 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); |
| 1780 if (request_->method == "HEAD") | 2090 if (request_->method == "HEAD") |
| 1781 return 0; | 2091 return 0; |
| 1782 | 2092 |
| 1783 DCHECK(entry_); | 2093 DCHECK(entry_); |
| 1784 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; | 2094 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; |
| 1785 | 2095 |
| 1786 if (net_log_.IsCapturing()) | 2096 if (net_log_.IsCapturing()) |
| 1787 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); | 2097 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1829 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; | 2139 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; |
| 1830 write_len_ = num_bytes; | 2140 write_len_ = num_bytes; |
| 1831 if (entry_) { | 2141 if (entry_) { |
| 1832 if (net_log_.IsCapturing()) | 2142 if (net_log_.IsCapturing()) |
| 1833 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); | 2143 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); |
| 1834 } | 2144 } |
| 1835 | 2145 |
| 1836 if (!entry_ || !num_bytes) | 2146 if (!entry_ || !num_bytes) |
| 1837 return num_bytes; | 2147 return num_bytes; |
| 1838 | 2148 |
| 1839 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2149 if (partial_) { |
| 1840 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), | 2150 return partial_->CacheWrite(entry_->disk_entry, read_buf_.get(), num_bytes, |
| 1841 num_bytes, io_callback_); | 2151 io_callback_); |
| 2152 } | |
| 2153 DCHECK(data_access_); | |
| 2154 return data_access_->CacheWrite(read_buf_, num_bytes, io_callback_); | |
| 1842 } | 2155 } |
| 1843 | 2156 |
| 1844 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { | 2157 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { |
| 1845 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); | 2158 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); |
| 1846 if (entry_) { | 2159 if (entry_) { |
| 1847 if (net_log_.IsCapturing()) { | 2160 if (net_log_.IsCapturing()) { |
| 1848 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, | 2161 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, |
| 1849 result); | 2162 result); |
| 1850 } | 2163 } |
| 1851 } | 2164 } |
| 1852 if (!cache_.get()) | 2165 if (!cache_.get()) |
| 1853 return ERR_UNEXPECTED; | 2166 return ERR_UNEXPECTED; |
| 1854 | 2167 |
| 1855 if (result != write_len_) { | 2168 if (result != write_len_) { |
| 1856 DLOG(ERROR) << "failed to write response data to cache"; | 2169 DLOG(ERROR) << "failed to write response data to cache"; |
| 1857 DoneWritingToEntry(false); | 2170 DoneWritingToEntry(false); |
| 1858 | 2171 |
| 1859 // We want to ignore errors writing to disk and just keep reading from | 2172 // We want to ignore errors writing to disk and just keep reading from |
| 1860 // the network. | 2173 // the network. |
| 1861 result = write_len_; | 2174 result = write_len_; |
| 1862 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) { | 2175 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) { |
| 1863 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2176 done_reading_ = cache_->IsResponseCompleted(entry_, &response_); |
| 1864 int64_t body_size = response_.headers->GetContentLength(); | |
| 1865 if (body_size >= 0 && body_size <= current_size) | |
| 1866 done_reading_ = true; | |
| 1867 } | 2177 } |
| 1868 | 2178 |
| 1869 if (partial_) { | 2179 if (partial_) { |
| 1870 // This may be the last request. | 2180 // This may be the last request. |
| 1871 if (result != 0 || truncated_ || | 2181 if (result != 0 || truncated_ || |
| 1872 !(partial_->IsLastRange() || mode_ == WRITE)) { | 2182 !(partial_->IsLastRange() || mode_ == WRITE)) { |
| 1873 return DoPartialNetworkReadCompleted(result); | 2183 return DoPartialNetworkReadCompleted(result); |
| 1874 } | 2184 } |
| 1875 } | 2185 } |
| 1876 | 2186 |
| 2187 // End of file. This may be the result of a connection problem so see if we | |
| 2188 // have to keep the entry around to be flagged as truncated later on. | |
| 1877 if (result == 0) { | 2189 if (result == 0) { |
| 1878 // End of file. This may be the result of a connection problem so see if we | |
| 1879 // have to keep the entry around to be flagged as truncated later on. | |
| 1880 if (done_reading_ || !entry_ || partial_ || | 2190 if (done_reading_ || !entry_ || partial_ || |
| 1881 response_.headers->GetContentLength() <= 0) { | 2191 response_.headers->GetContentLength() <= 0) |
| 1882 DoneWritingToEntry(true); | 2192 DoneWritingToEntry(true); |
| 1883 } | |
| 1884 } | 2193 } |
| 1885 | 2194 |
| 1886 return result; | 2195 return result; |
| 1887 } | 2196 } |
| 1888 | 2197 |
| 1889 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { | 2198 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { |
| 1890 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); | 2199 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); |
| 1891 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; | 2200 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; |
| 1892 return WriteResponseInfoToEntry(true); | 2201 return WriteResponseInfoToEntry(true); |
| 1893 } | 2202 } |
| 1894 | 2203 |
| 1895 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { | 2204 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { |
| 1896 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); | 2205 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); |
| 1897 | 2206 |
| 1898 return OnWriteResponseInfoToEntryComplete(result); | 2207 return OnWriteResponseInfoToEntryComplete(result); |
| 1899 } | 2208 } |
| 1900 | 2209 |
| 2210 int HttpCache::Transaction::DoSharedReadWriteFailed() { | |
| 2211 if (net_log_.IsCapturing()) | |
| 2212 net_log_.EndEventWithNetErrorCode( | |
| 2213 NetLogEventType::HTTP_CACHE_SHARED_READ_WRITE_FAILED, | |
| 2214 shared_read_write_failure_result_); | |
| 2215 | |
| 2216 return shared_read_write_failure_result_; | |
| 2217 } | |
| 2218 | |
| 1901 //----------------------------------------------------------------------------- | 2219 //----------------------------------------------------------------------------- |
| 1902 | 2220 |
| 1903 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, | 2221 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, |
| 1904 const HttpRequestInfo* request) { | 2222 const HttpRequestInfo* request) { |
| 1905 net_log_ = net_log; | 2223 net_log_ = net_log; |
| 1906 request_ = request; | 2224 request_ = request; |
| 1907 effective_load_flags_ = request_->load_flags; | 2225 effective_load_flags_ = request_->load_flags; |
| 1908 | 2226 |
| 1909 if (cache_->mode() == DISABLE) | 2227 if (cache_->mode() == DISABLE) |
| 1910 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 2228 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2084 | 2402 |
| 2085 if (partial_ && (is_sparse_ || truncated_) && | 2403 if (partial_ && (is_sparse_ || truncated_) && |
| 2086 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 2404 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
| 2087 // Force revalidation for sparse or truncated entries. Note that we don't | 2405 // Force revalidation for sparse or truncated entries. Note that we don't |
| 2088 // want to ignore the regular validation logic just because a byte range was | 2406 // want to ignore the regular validation logic just because a byte range was |
| 2089 // part of the request. | 2407 // part of the request. |
| 2090 skip_validation = false; | 2408 skip_validation = false; |
| 2091 } | 2409 } |
| 2092 | 2410 |
| 2093 if (skip_validation) { | 2411 if (skip_validation) { |
| 2094 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); | 2412 if (shared_) { |
| 2095 return SetupEntryForRead(); | 2413 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING); |
| 2414 entry_->shared_writers->OnValidationMatch(this, priority_); | |
| 2415 } else { | |
| 2416 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); | |
| 2417 return SetupEntryForRead(); | |
| 2418 } | |
| 2096 } else { | 2419 } else { |
| 2097 // Make the network request conditional, to see if we may reuse our cached | 2420 // Make the network request conditional, to see if we may reuse our cached |
| 2098 // response. If we cannot do so, then we just resort to a normal fetch. | 2421 // response. If we cannot do so, then we just resort to a normal fetch. |
| 2099 // Our mode remains READ_WRITE for a conditional request. Even if the | 2422 // Our mode remains READ_WRITE for a conditional request. Even if the |
| 2100 // conditionalization fails, we don't switch to WRITE mode until we | 2423 // conditionalization fails, we don't switch to WRITE mode until we |
| 2101 // know we won't be falling back to using the cache entry in the | 2424 // know we won't be falling back to using the cache entry in the |
| 2102 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2425 // LOAD_FROM_CACHE_IF_OFFLINE case. |
| 2103 if (!ConditionalizeRequest()) { | 2426 if (!ConditionalizeRequest()) { |
| 2104 couldnt_conditionalize_request_ = true; | 2427 couldnt_conditionalize_request_ = true; |
| 2105 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); | 2428 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2604 IsCertStatusError(response_.ssl_info.cert_status)) { | 2927 IsCertStatusError(response_.ssl_info.cert_status)) { |
| 2605 DoneWritingToEntry(false); | 2928 DoneWritingToEntry(false); |
| 2606 if (net_log_.IsCapturing()) | 2929 if (net_log_.IsCapturing()) |
| 2607 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); | 2930 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); |
| 2608 return OK; | 2931 return OK; |
| 2609 } | 2932 } |
| 2610 | 2933 |
| 2611 if (truncated) | 2934 if (truncated) |
| 2612 DCHECK_EQ(200, response_.headers->response_code()); | 2935 DCHECK_EQ(200, response_.headers->response_code()); |
| 2613 | 2936 |
| 2614 // When writing headers, we normally only write the non-transient headers. | 2937 return cache_->WriteResponseInfo(entry_, &response_, io_callback_, truncated, |
| 2615 bool skip_transient_headers = true; | 2938 &io_buf_len_); |
| 2616 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); | |
| 2617 response_.Persist(data->pickle(), skip_transient_headers, truncated); | |
| 2618 data->Done(); | |
| 2619 | |
| 2620 io_buf_len_ = data->pickle()->size(); | |
| 2621 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(), | |
| 2622 io_buf_len_, io_callback_, true); | |
| 2623 } | 2939 } |
| 2624 | 2940 |
| 2625 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { | 2941 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { |
| 2626 if (!entry_) | 2942 if (!entry_) |
| 2627 return OK; | 2943 return OK; |
| 2628 if (net_log_.IsCapturing()) { | 2944 if (net_log_.IsCapturing()) { |
| 2629 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, | 2945 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, |
| 2630 result); | 2946 result); |
| 2631 } | 2947 } |
| 2632 | 2948 |
| 2633 if (result != io_buf_len_) { | 2949 if (result != io_buf_len_) { |
| 2634 DLOG(ERROR) << "failed to write response info to cache"; | 2950 DLOG(ERROR) << "failed to write response info to cache"; |
| 2635 DoneWritingToEntry(false); | 2951 DoneWritingToEntry(false); |
| 2636 } | 2952 } |
| 2637 return OK; | 2953 return OK; |
| 2638 } | 2954 } |
| 2639 | 2955 |
| 2640 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2956 void HttpCache::Transaction::DoneWritingToEntry(bool success, |
| 2957 bool perform_entry_cleanup) { | |
| 2641 if (!entry_) | 2958 if (!entry_) |
| 2642 return; | 2959 return; |
| 2643 | 2960 |
| 2644 RecordHistograms(); | 2961 RecordHistograms(); |
| 2645 | 2962 |
| 2646 cache_->DoneWritingToEntry(entry_, success); | 2963 if (perform_entry_cleanup) { |
| 2647 entry_ = NULL; | 2964 cache_->DoneWritingToEntry(entry_, success); |
| 2965 } | |
| 2966 entry_ = nullptr; | |
| 2648 mode_ = NONE; // switch to 'pass through' mode | 2967 mode_ = NONE; // switch to 'pass through' mode |
| 2649 } | 2968 } |
| 2650 | 2969 |
| 2970 void HttpCache::Transaction::ContinueWithoutSharedWriting( | |
| 2971 std::unique_ptr<DataAccess> data_access, | |
| 2972 bool needs_entry) { | |
| 2973 shared_ = false; | |
| 2974 if (!needs_entry) | |
| 2975 entry_ = nullptr; | |
| 2976 mode_ = NONE; | |
| 2977 data_access_ = std::move(data_access); | |
| 2978 } | |
| 2979 | |
| 2651 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2980 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
| 2652 DLOG(ERROR) << "ReadData failed: " << result; | 2981 DLOG(ERROR) << "ReadData failed: " << result; |
| 2653 const int result_for_histogram = std::max(0, -result); | 2982 const int result_for_histogram = std::max(0, -result); |
| 2654 if (restart) { | 2983 if (restart) { |
| 2655 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", | 2984 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", |
| 2656 result_for_histogram); | 2985 result_for_histogram); |
| 2657 } else { | 2986 } else { |
| 2658 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", | 2987 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", |
| 2659 result_for_histogram); | 2988 result_for_histogram); |
| 2660 } | 2989 } |
| 2661 | 2990 |
| 2662 // Avoid using this entry in the future. | 2991 // Avoid using this entry in the future. |
| 2663 if (cache_.get()) | 2992 if (cache_.get()) |
| 2664 cache_->DoomActiveEntry(cache_key_); | 2993 cache_->DoomActiveEntry(cache_key_); |
| 2665 | 2994 |
| 2666 if (restart) { | 2995 if (restart) { |
| 2667 DCHECK(!reading_); | 2996 DCHECK(!reading_); |
| 2668 DCHECK(!network_trans_.get()); | 2997 DCHECK(!network_trans_.get()); |
| 2669 cache_->DoneWithEntry(entry_, this, false); | 2998 if (shared_) { |
| 2999 cache_->RemoveValidatingTransSharedWriters(this, entry_); | |
| 3000 } else { | |
| 3001 cache_->DoneWithEntry(entry_, this, false); | |
| 3002 } | |
| 2670 entry_ = NULL; | 3003 entry_ = NULL; |
| 2671 is_sparse_ = false; | 3004 is_sparse_ = false; |
| 2672 partial_.reset(); | 3005 partial_.reset(); |
| 2673 next_state_ = STATE_GET_BACKEND; | 3006 next_state_ = STATE_GET_BACKEND; |
| 2674 return OK; | 3007 return OK; |
| 2675 } | 3008 } |
| 2676 | 3009 |
| 2677 return ERR_CACHE_READ_FAILURE; | 3010 return ERR_CACHE_READ_FAILURE; |
| 2678 } | 3011 } |
| 2679 | 3012 |
| 2680 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { | 3013 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { |
| 2681 if (entry_lock_waiting_since_ != start_time) | 3014 if (entry_lock_waiting_since_ != start_time) |
| 2682 return; | 3015 return; |
| 2683 | 3016 |
| 2684 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); | 3017 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); |
| 2685 | 3018 |
| 2686 if (!cache_) | 3019 if (!cache_) |
| 2687 return; | 3020 return; |
| 2688 | 3021 |
| 2689 cache_->RemovePendingTransaction(this); | 3022 cache_->RemovePendingTransaction(this); |
| 2690 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); | 3023 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); |
| 2691 } | 3024 } |
| 2692 | 3025 |
| 2693 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { | 3026 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { |
| 3027 // Partial requests not supported with shared writing as of now. | |
| 3028 DCHECK(!shared_); | |
| 2694 DVLOG(2) << "DoomPartialEntry"; | 3029 DVLOG(2) << "DoomPartialEntry"; |
| 2695 int rv = cache_->DoomEntry(cache_key_, NULL); | 3030 int rv = cache_->DoomEntry(cache_key_, NULL); |
| 2696 DCHECK_EQ(OK, rv); | 3031 DCHECK_EQ(OK, rv); |
| 2697 cache_->DoneWithEntry(entry_, this, false); | 3032 cache_->DoneWithEntry(entry_, this, false); |
| 2698 entry_ = NULL; | 3033 entry_ = NULL; |
| 2699 is_sparse_ = false; | 3034 is_sparse_ = false; |
| 2700 truncated_ = false; | 3035 truncated_ = false; |
| 2701 if (delete_object) | 3036 if (delete_object) |
| 2702 partial_.reset(NULL); | 3037 partial_.reset(NULL); |
| 2703 } | 3038 } |
| 2704 | 3039 |
| 2705 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { | 3040 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { |
| 2706 partial_->OnNetworkReadCompleted(result); | 3041 partial_->OnNetworkReadCompleted(result); |
| 2707 | 3042 |
| 2708 if (result == 0) { | 3043 if (result == 0) { |
| 2709 // We need to move on to the next range. | 3044 // We need to move on to the next range. |
| 2710 ResetNetworkTransaction(); | 3045 ResetDataAccess(); |
| 2711 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; | 3046 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; |
| 2712 } | 3047 } |
| 2713 return result; | 3048 return result; |
| 2714 } | 3049 } |
| 2715 | 3050 |
| 2716 int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) { | 3051 int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) { |
| 2717 partial_->OnCacheReadCompleted(result); | 3052 partial_->OnCacheReadCompleted(result); |
| 2718 | 3053 |
| 2719 if (result == 0 && mode_ == READ_WRITE) { | 3054 if (result == 0 && mode_ == READ_WRITE) { |
| 2720 // We need to move on to the next range. | 3055 // We need to move on to the next range. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2744 if (!delete_object) { | 3079 if (!delete_object) { |
| 2745 // The simplest way to re-initialize partial_ is to create a new object. | 3080 // The simplest way to re-initialize partial_ is to create a new object. |
| 2746 partial_.reset(new PartialData()); | 3081 partial_.reset(new PartialData()); |
| 2747 if (partial_->Init(request_->extra_headers)) | 3082 if (partial_->Init(request_->extra_headers)) |
| 2748 partial_->SetHeaders(custom_request_->extra_headers); | 3083 partial_->SetHeaders(custom_request_->extra_headers); |
| 2749 else | 3084 else |
| 2750 partial_.reset(); | 3085 partial_.reset(); |
| 2751 } | 3086 } |
| 2752 } | 3087 } |
| 2753 | 3088 |
| 2754 void HttpCache::Transaction::ResetNetworkTransaction() { | 3089 void HttpCache::Transaction::SaveNetworkTransactionInfo( |
| 3090 const HttpTransaction* transaction) { | |
| 2755 DCHECK(!old_network_trans_load_timing_); | 3091 DCHECK(!old_network_trans_load_timing_); |
| 2756 DCHECK(network_trans_); | 3092 DCHECK(transaction); |
| 2757 LoadTimingInfo load_timing; | 3093 LoadTimingInfo load_timing; |
| 2758 if (network_trans_->GetLoadTimingInfo(&load_timing)) | 3094 if (transaction->GetLoadTimingInfo(&load_timing)) |
| 2759 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); | 3095 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); |
| 2760 total_received_bytes_ += network_trans_->GetTotalReceivedBytes(); | 3096 total_received_bytes_ += transaction->GetTotalReceivedBytes(); |
| 2761 total_sent_bytes_ += network_trans_->GetTotalSentBytes(); | 3097 total_sent_bytes_ += transaction->GetTotalSentBytes(); |
| 2762 ConnectionAttempts attempts; | 3098 ConnectionAttempts attempts; |
| 2763 network_trans_->GetConnectionAttempts(&attempts); | 3099 transaction->GetConnectionAttempts(&attempts); |
| 2764 for (const auto& attempt : attempts) | 3100 for (const auto& attempt : attempts) |
| 2765 old_connection_attempts_.push_back(attempt); | 3101 old_connection_attempts_.push_back(attempt); |
| 2766 old_remote_endpoint_ = IPEndPoint(); | 3102 old_remote_endpoint_ = IPEndPoint(); |
| 2767 network_trans_->GetRemoteEndpoint(&old_remote_endpoint_); | 3103 transaction->GetRemoteEndpoint(&old_remote_endpoint_); |
| 3104 } | |
| 3105 | |
| 3106 void HttpCache::Transaction::SaveSharedNetworkTransactionInfo() { | |
| 3107 // If network_trans_ is still present, this transaction has not started using | |
| 3108 // the "shared" network transaction. | |
| 3109 if (network_trans_) { | |
| 3110 SaveNetworkTransactionInfo(network_trans_.get()); | |
| 3111 return; | |
| 3112 } | |
| 3113 | |
| 3114 DCHECK(!old_network_trans_load_timing_); | |
| 3115 | |
| 3116 // If the transaction is being deleted while still in the waiting queue, | |
| 3117 // entry_ is not yet set, do nothing. | |
| 3118 if (!entry_) | |
| 3119 return; | |
| 3120 DCHECK(entry_->shared_writers); | |
| 3121 HttpTransaction* network_transaction = | |
| 3122 entry_->shared_writers->data_access_->network_transaction_.get(); | |
| 3123 SaveNetworkTransactionInfo(network_transaction); | |
| 3124 have_full_request_headers_ = | |
| 3125 network_transaction->GetFullRequestHeaders(&full_request_headers_); | |
| 3126 } | |
| 3127 | |
| 3128 void HttpCache::Transaction::ResetNetworkTransaction() { | |
| 3129 SaveNetworkTransactionInfo(network_trans_.get()); | |
| 2768 network_trans_.reset(); | 3130 network_trans_.reset(); |
| 2769 } | 3131 } |
| 2770 | 3132 |
| 2771 // Histogram data from the end of 2010 show the following distribution of | 3133 void HttpCache::Transaction::ResetDataAccess() { |
| 2772 // response headers: | 3134 SaveNetworkTransactionInfo(data_access_->network_transaction_.get()); |
| 2773 // | 3135 data_access_.reset(); |
| 2774 // Content-Length............... 87% | 3136 } |
| 2775 // Date......................... 98% | |
| 2776 // Last-Modified................ 49% | |
| 2777 // Etag......................... 19% | |
| 2778 // Accept-Ranges: bytes......... 25% | |
| 2779 // Accept-Ranges: none.......... 0.4% | |
| 2780 // Strong Validator............. 50% | |
| 2781 // Strong Validator + ranges.... 24% | |
| 2782 // Strong Validator + CL........ 49% | |
| 2783 // | |
| 2784 bool HttpCache::Transaction::CanResume(bool has_data) { | |
| 2785 // Double check that there is something worth keeping. | |
| 2786 if (has_data && !entry_->disk_entry->GetDataSize(kResponseContentIndex)) | |
| 2787 return false; | |
| 2788 | 3137 |
| 2789 if (request_->method != "GET") | 3138 HttpTransaction* HttpCache::Transaction::GetCurrentNetworkTransaction() const { |
| 2790 return false; | 3139 if (network_trans_) |
| 2791 | 3140 return network_trans_.get(); |
| 2792 // Note that if this is a 206, content-length was already fixed after calling | 3141 if (data_access_) |
| 2793 // PartialData::ResponseHeadersOK(). | 3142 return data_access_->network_transaction_.get(); |
| 2794 if (response_.headers->GetContentLength() <= 0 || | 3143 if (shared_ && entry_ && entry_->shared_writers) |
| 2795 response_.headers->HasHeaderValue("Accept-Ranges", "none") || | 3144 return entry_->shared_writers->data_access_->network_transaction_.get(); |
| 2796 !response_.headers->HasStrongValidators()) { | 3145 return nullptr; |
| 2797 return false; | |
| 2798 } | |
| 2799 | |
| 2800 return true; | |
| 2801 } | 3146 } |
| 2802 | 3147 |
| 2803 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { | 3148 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { |
| 2804 response_ = response; | 3149 response_ = response; |
| 2805 SyncCacheEntryStatusToResponse(); | 3150 SyncCacheEntryStatusToResponse(); |
| 2806 } | 3151 } |
| 2807 | 3152 |
| 2808 void HttpCache::Transaction::SetAuthResponse( | 3153 void HttpCache::Transaction::SetAuthResponse( |
| 2809 const HttpResponseInfo& auth_response) { | 3154 const HttpResponseInfo& auth_response) { |
| 2810 auth_response_ = auth_response; | 3155 auth_response_ = auth_response; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2916 } | 3261 } |
| 2917 } | 3262 } |
| 2918 | 3263 |
| 2919 CACHE_STATUS_HISTOGRAMS(""); | 3264 CACHE_STATUS_HISTOGRAMS(""); |
| 2920 | 3265 |
| 2921 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { | 3266 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { |
| 2922 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", | 3267 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", |
| 2923 validation_cause_, VALIDATION_CAUSE_MAX); | 3268 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2924 } | 3269 } |
| 2925 | 3270 |
| 3271 // This may also exclude shared writing counts for these cases. | |
| 2926 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) | 3272 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) |
| 2927 return; | 3273 return; |
| 3274 | |
| 2928 DCHECK(!range_requested_); | 3275 DCHECK(!range_requested_); |
| 2929 DCHECK(!first_cache_access_since_.is_null()); | 3276 DCHECK(!first_cache_access_since_.is_null()); |
| 2930 | 3277 |
| 2931 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; | 3278 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2932 | 3279 |
| 2933 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); | 3280 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2934 | 3281 |
| 3282 if (cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING) { | |
| 3283 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.JoinSharedWriting", total_time); | |
| 3284 } else if (cache_entry_status_ == | |
| 3285 CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING) { | |
| 3286 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.DoomSharedWriting", total_time); | |
| 3287 } else if (initiate_shared_writing_) { | |
| 3288 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.InitiateSharedWriting", | |
| 3289 total_time); | |
| 3290 } | |
| 3291 | |
| 2935 bool did_send_request = !send_request_since_.is_null(); | 3292 bool did_send_request = !send_request_since_.is_null(); |
| 2936 DCHECK( | 3293 DCHECK( |
| 2937 (did_send_request && | 3294 (did_send_request && |
| 2938 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || | 3295 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || |
| 2939 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || | 3296 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || |
| 2940 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || | 3297 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || |
| 2941 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE)) || | 3298 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE || |
| 3299 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING || | |
| 3300 cache_entry_status_ == CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING)) || | |
| 2942 (!did_send_request && | 3301 (!did_send_request && |
| 2943 cache_entry_status_ == CacheEntryStatus::ENTRY_USED)); | 3302 (cache_entry_status_ == CacheEntryStatus::ENTRY_USED || |
| 3303 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING))); | |
| 2944 | 3304 |
| 2945 if (!did_send_request) { | 3305 if (!did_send_request) { |
| 2946 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_USED); | 3306 if (cache_entry_status_ == CacheEntryStatus::ENTRY_USED) { |
| 2947 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); | 3307 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); |
| 3308 } | |
| 2948 return; | 3309 return; |
| 2949 } | 3310 } |
| 2950 | 3311 |
| 2951 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; | 3312 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; |
| 2952 int64_t before_send_percent = (total_time.ToInternalValue() == 0) | 3313 int64_t before_send_percent = (total_time.ToInternalValue() == 0) |
| 2953 ? 0 | 3314 ? 0 |
| 2954 : before_send_time * 100 / total_time; | 3315 : before_send_time * 100 / total_time; |
| 2955 DCHECK_GE(before_send_percent, 0); | 3316 DCHECK_GE(before_send_percent, 0); |
| 2956 DCHECK_LE(before_send_percent, 100); | 3317 DCHECK_LE(before_send_percent, 100); |
| 2957 base::HistogramBase::Sample before_send_sample = | 3318 base::HistogramBase::Sample before_send_sample = |
| 2958 static_cast<base::HistogramBase::Sample>(before_send_percent); | 3319 static_cast<base::HistogramBase::Sample>(before_send_percent); |
| 2959 | 3320 |
| 2960 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); | 3321 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); |
| 2961 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); | 3322 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); |
| 2962 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); | 3323 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); |
| 2963 | 3324 |
| 2964 // TODO(gavinp): Remove or minimize these histograms, particularly the ones | 3325 // TODO(gavinp): Remove or minimize these histograms, particularly the ones |
| 2965 // below this comment after we have received initial data. | 3326 // below this comment after we have received initial data. |
| 2966 switch (cache_entry_status_) { | 3327 switch (cache_entry_status_) { |
| 2967 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: { | 3328 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: { |
| 2968 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", | 3329 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", |
| 2969 before_send_time); | 3330 before_send_time); |
| 2970 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", | 3331 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", |
| 2971 before_send_sample); | 3332 before_send_sample); |
| 3333 if (initiate_shared_writing_) { | |
| 3334 UMA_HISTOGRAM_TIMES( | |
| 3335 "HttpCache.BeforeSend.CantConditionalize.InitiateSharedWriting", | |
| 3336 before_send_time); | |
| 3337 UMA_HISTOGRAM_PERCENTAGE( | |
| 3338 "HttpCache.PercentBeforeSend.CantConditionalize." | |
| 3339 "InitiateSharedWriting", | |
| 3340 before_send_sample); | |
| 3341 } | |
| 3342 | |
| 2972 break; | 3343 break; |
| 2973 } | 3344 } |
| 2974 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: { | 3345 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: { |
| 2975 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); | 3346 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); |
| 2976 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", | 3347 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", |
| 2977 before_send_sample); | 3348 before_send_sample); |
| 3349 if (initiate_shared_writing_) { | |
| 3350 UMA_HISTOGRAM_TIMES( | |
| 3351 "HttpCache.BeforeSend.NotCached.InitiateSharedWriting", | |
| 3352 before_send_time); | |
| 3353 UMA_HISTOGRAM_PERCENTAGE( | |
| 3354 "HttpCache.PercentBeforeSend.NotCached.InitiateSharedWriting", | |
| 3355 before_send_sample); | |
| 3356 } | |
| 3357 | |
| 2978 break; | 3358 break; |
| 2979 } | 3359 } |
| 2980 case CacheEntryStatus::ENTRY_VALIDATED: { | 3360 case CacheEntryStatus::ENTRY_VALIDATED: { |
| 2981 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); | 3361 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); |
| 2982 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", | 3362 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", |
| 2983 before_send_sample); | 3363 before_send_sample); |
| 2984 break; | 3364 break; |
| 2985 } | 3365 } |
| 2986 case CacheEntryStatus::ENTRY_UPDATED: { | 3366 case CacheEntryStatus::ENTRY_UPDATED: { |
| 2987 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); | 3367 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); |
| 2988 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", | 3368 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", |
| 2989 before_send_sample); | 3369 before_send_sample); |
| 3370 if (initiate_shared_writing_) { | |
| 3371 UMA_HISTOGRAM_TIMES( | |
| 3372 "HttpCache.BeforeSend.Updated.InitiateSharedWriting", | |
| 3373 before_send_time); | |
| 3374 UMA_HISTOGRAM_PERCENTAGE( | |
| 3375 "HttpCache.PercentBeforeSend.Updated.InitiateSharedWriting", | |
| 3376 before_send_sample); | |
| 3377 } | |
| 3378 break; | |
| 3379 } | |
| 3380 case CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING: { | |
| 3381 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.JoinSharedWriting", | |
| 3382 before_send_time); | |
| 3383 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.JoinSharedWriting", | |
| 3384 before_send_sample); | |
| 3385 break; | |
| 3386 } | |
| 3387 case CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING: { | |
| 3388 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.DoomSharedWriting", | |
| 3389 before_send_time); | |
| 3390 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.DoomSharedWriting", | |
| 3391 before_send_sample); | |
| 2990 break; | 3392 break; |
| 2991 } | 3393 } |
| 2992 default: | 3394 default: |
| 2993 NOTREACHED(); | 3395 NOTREACHED(); |
| 2994 } | 3396 } |
| 2995 } | 3397 } |
| 2996 | 3398 |
| 3399 bool HttpCache::Transaction::IsEligibleForSharedWriting() const { | |
| 3400 if (!(mode_ & WRITE)) | |
| 3401 return false; | |
| 3402 | |
| 3403 DCHECK(request_); | |
| 3404 if (request_->method != "GET") | |
| 3405 return false; | |
| 3406 | |
| 3407 if (partial_ || range_requested_) | |
| 3408 return false; | |
| 3409 | |
| 3410 return true; | |
| 3411 } | |
| 3412 | |
| 3413 void HttpCache::Transaction::SetSharedWritingFailState(int result) { | |
| 3414 next_state_ = STATE_SHARED_READ_WRITE_FAILED; | |
| 3415 shared_read_write_failure_result_ = result; | |
| 3416 entry_ = nullptr; | |
| 3417 } | |
| 3418 | |
| 2997 void HttpCache::Transaction::OnIOComplete(int result) { | 3419 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2998 DoLoop(result); | 3420 DoLoop(result); |
| 2999 } | 3421 } |
| 3000 | 3422 |
| 3001 } // namespace net | 3423 } // namespace net |
| OLD | NEW |