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> |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 truncated_(false), | 173 truncated_(false), |
| 174 is_sparse_(false), | 174 is_sparse_(false), |
| 175 range_requested_(false), | 175 range_requested_(false), |
| 176 handling_206_(false), | 176 handling_206_(false), |
| 177 cache_pending_(false), | 177 cache_pending_(false), |
| 178 done_reading_(false), | 178 done_reading_(false), |
| 179 vary_mismatch_(false), | 179 vary_mismatch_(false), |
| 180 couldnt_conditionalize_request_(false), | 180 couldnt_conditionalize_request_(false), |
| 181 bypass_lock_for_test_(false), | 181 bypass_lock_for_test_(false), |
| 182 fail_conditionalization_for_test_(false), | 182 fail_conditionalization_for_test_(false), |
| 183 shared_(false), | |
| 184 finalize_doomed_(false), | |
| 185 orphaned_(false), | |
| 183 io_buf_len_(0), | 186 io_buf_len_(0), |
| 184 read_offset_(0), | 187 read_offset_(0), |
| 185 effective_load_flags_(0), | 188 effective_load_flags_(0), |
| 186 write_len_(0), | 189 write_len_(0), |
| 187 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED), | 190 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED), |
| 188 validation_cause_(VALIDATION_CAUSE_UNDEFINED), | 191 validation_cause_(VALIDATION_CAUSE_UNDEFINED), |
| 189 total_received_bytes_(0), | 192 total_received_bytes_(0), |
| 190 total_sent_bytes_(0), | 193 total_sent_bytes_(0), |
| 191 websocket_handshake_stream_base_create_helper_(NULL), | 194 websocket_handshake_stream_base_create_helper_(NULL), |
| 195 have_full_request_headers_(false), | |
| 192 weak_factory_(this) { | 196 weak_factory_(this) { |
| 193 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction"); | 197 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction"); |
| 194 static_assert(HttpCache::Transaction::kNumValidationHeaders == | 198 static_assert(HttpCache::Transaction::kNumValidationHeaders == |
| 195 arraysize(kValidationHeaders), | 199 arraysize(kValidationHeaders), |
| 196 "invalid number of validation headers"); | 200 "invalid number of validation headers"); |
| 197 | 201 |
| 198 io_callback_ = base::Bind(&Transaction::OnIOComplete, | 202 io_callback_ = base::Bind(&Transaction::OnIOComplete, |
| 199 weak_factory_.GetWeakPtr()); | 203 weak_factory_.GetWeakPtr()); |
| 200 } | 204 } |
| 201 | 205 |
| 202 HttpCache::Transaction::~Transaction() { | 206 HttpCache::Transaction::~Transaction() { |
| 203 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); | 207 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); |
| 208 | |
| 209 // Assert to make sure that any owner of HttpCache::Transaction always invokes | |
| 210 // Orphan and not the destructor directly. | |
| 211 DCHECK(orphaned_); | |
| 212 | |
| 204 // We may have to issue another IO, but we should never invoke the callback_ | 213 // We may have to issue another IO, but we should never invoke the callback_ |
| 205 // after this point. | 214 // after this point. |
| 206 callback_.Reset(); | 215 callback_.Reset(); |
| 216 weak_factory_.InvalidateWeakPtrs(); | |
| 207 | 217 |
| 208 if (cache_) { | 218 if (cache_) { |
| 209 if (entry_) { | 219 if (entry_ && !finalize_doomed_) { |
| 210 bool cancel_request = reading_ && response_.headers.get(); | 220 bool cancel_request = reading_ && response_.headers.get(); |
| 211 if (cancel_request) { | 221 if (cancel_request) { |
| 212 if (partial_) { | 222 if (partial_) { |
| 213 entry_->disk_entry->CancelSparseIO(); | 223 entry_->disk_entry->CancelSparseIO(); |
| 214 } else { | 224 } else { |
| 215 cancel_request &= (response_.headers->response_code() == 200); | 225 cancel_request &= (response_.headers->response_code() == 200); |
| 216 } | 226 } |
| 217 } | 227 } |
| 218 | |
| 219 cache_->DoneWithEntry(entry_, this, cancel_request); | 228 cache_->DoneWithEntry(entry_, this, cancel_request); |
| 220 } else if (cache_pending_) { | 229 } else if (cache_pending_) { |
| 221 cache_->RemovePendingTransaction(this); | 230 cache_->RemovePendingTransaction(this); |
| 222 } | 231 } |
| 223 } | 232 } |
| 224 } | 233 } |
| 225 | 234 |
| 226 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, | 235 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, |
| 227 const CompletionCallback& callback) { | 236 const CompletionCallback& callback) { |
| 228 DCHECK(buf); | 237 DCHECK(buf); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 255 | 264 |
| 256 truncated_ = true; | 265 truncated_ = true; |
| 257 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; | 266 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; |
| 258 DoLoop(OK); | 267 DoLoop(OK); |
| 259 return true; | 268 return true; |
| 260 } | 269 } |
| 261 | 270 |
| 262 LoadState HttpCache::Transaction::GetWriterLoadState() const { | 271 LoadState HttpCache::Transaction::GetWriterLoadState() const { |
| 263 if (network_trans_.get()) | 272 if (network_trans_.get()) |
| 264 return network_trans_->GetLoadState(); | 273 return network_trans_->GetLoadState(); |
| 274 if (shared_ && entry_) | |
| 275 return entry_->shared_writers->GetLoadState(); | |
| 265 if (entry_ || !request_) | 276 if (entry_ || !request_) |
| 266 return LOAD_STATE_IDLE; | 277 return LOAD_STATE_IDLE; |
| 267 return LOAD_STATE_WAITING_FOR_CACHE; | 278 return LOAD_STATE_WAITING_FOR_CACHE; |
| 268 } | 279 } |
| 269 | 280 |
| 270 const NetLogWithSource& HttpCache::Transaction::net_log() const { | 281 const NetLogWithSource& HttpCache::Transaction::net_log() const { |
| 271 return net_log_; | 282 return net_log_; |
| 272 } | 283 } |
| 273 | 284 |
| 274 int HttpCache::Transaction::Start(const HttpRequestInfo* request, | 285 int HttpCache::Transaction::Start(const HttpRequestInfo* request, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 } | 375 } |
| 365 | 376 |
| 366 bool HttpCache::Transaction::IsReadyToRestartForAuth() { | 377 bool HttpCache::Transaction::IsReadyToRestartForAuth() { |
| 367 if (!network_trans_.get()) | 378 if (!network_trans_.get()) |
| 368 return false; | 379 return false; |
| 369 return network_trans_->IsReadyToRestartForAuth(); | 380 return network_trans_->IsReadyToRestartForAuth(); |
| 370 } | 381 } |
| 371 | 382 |
| 372 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, | 383 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, |
| 373 const CompletionCallback& callback) { | 384 const CompletionCallback& callback) { |
| 385 if (next_state_ == STATE_SHARED_READ_WRITE_FAILED) { | |
| 386 return ERR_CACHE_WRITE_FAILURE; | |
| 387 } | |
| 388 | |
| 374 DCHECK_EQ(next_state_, STATE_NONE); | 389 DCHECK_EQ(next_state_, STATE_NONE); |
| 375 DCHECK(buf); | 390 DCHECK(buf); |
| 376 DCHECK_GT(buf_len, 0); | 391 DCHECK_GT(buf_len, 0); |
| 377 DCHECK(!callback.is_null()); | 392 DCHECK(!callback.is_null()); |
| 378 | 393 |
| 379 DCHECK(callback_.is_null()); | 394 DCHECK(callback_.is_null()); |
| 380 | 395 |
| 381 if (!cache_.get()) | 396 if (!cache_.get()) |
| 382 return ERR_UNEXPECTED; | 397 return ERR_UNEXPECTED; |
| 383 | 398 |
| 384 // If we have an intermediate auth response at this point, then it means the | 399 // If we have an intermediate auth response at this point, then it means the |
| 385 // user wishes to read the network response (the error page). If there is a | 400 // user wishes to read the network response (the error page). If there is a |
| 386 // previous response in the cache then we should leave it intact. | 401 // previous response in the cache then we should leave it intact. |
| 387 if (auth_response_.headers.get() && mode_ != NONE) { | 402 if (auth_response_.headers.get() && mode_ != NONE) { |
| 388 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); | 403 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); |
| 389 DCHECK(mode_ & WRITE); | 404 DCHECK(mode_ & WRITE); |
| 390 DoneWritingToEntry(mode_ == READ_WRITE); | 405 DoneWritingToEntry(mode_ == READ_WRITE); |
| 391 mode_ = NONE; | 406 mode_ = NONE; |
| 392 } | 407 } |
| 393 | 408 |
| 394 reading_ = true; | 409 reading_ = true; |
| 395 read_buf_ = buf; | 410 read_buf_ = buf; |
| 396 io_buf_len_ = buf_len; | 411 io_buf_len_ = buf_len; |
| 397 if (network_trans_) { | 412 if (network_trans_) { |
| 413 DCHECK(!shared_); | |
| 398 DCHECK(mode_ == WRITE || mode_ == NONE || | 414 DCHECK(mode_ == WRITE || mode_ == NONE || |
| 399 (mode_ == READ_WRITE && partial_)); | 415 (mode_ == READ_WRITE && partial_)); |
| 400 next_state_ = STATE_NETWORK_READ; | 416 next_state_ = STATE_NETWORK_READ; |
| 401 } else { | 417 } else if (!shared_) { |
| 402 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); | 418 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); |
| 403 next_state_ = STATE_CACHE_READ_DATA; | 419 next_state_ = STATE_CACHE_READ_DATA; |
| 420 } else { // uses SharedWriters | |
| 421 if (read_offset_ == entry_->disk_entry->GetDataSize(kResponseContentIndex)) | |
| 422 next_state_ = STATE_SHARED_NETWORK_READ; | |
| 423 else { | |
| 424 DCHECK_LT(read_offset_, | |
| 425 entry_->disk_entry->GetDataSize(kResponseContentIndex)); | |
| 426 next_state_ = STATE_CACHE_READ_DATA; | |
| 427 } | |
| 404 } | 428 } |
| 405 | 429 |
| 406 int rv = DoLoop(OK); | 430 int rv = DoLoop(OK); |
| 407 | 431 |
| 408 if (rv == ERR_IO_PENDING) { | 432 if (rv == ERR_IO_PENDING) { |
| 409 DCHECK(callback_.is_null()); | 433 DCHECK(callback_.is_null()); |
| 410 callback_ = callback; | 434 callback_ = callback; |
| 411 } | 435 } |
| 412 return rv; | 436 return rv; |
| 413 } | 437 } |
| 414 | 438 |
| 415 void HttpCache::Transaction::StopCaching() { | 439 void HttpCache::Transaction::StopCaching() { |
| 416 // We really don't know where we are now. Hopefully there is no operation in | 440 // We really don't know where we are now. Hopefully there is no operation in |
| 417 // progress, but nothing really prevents this method to be called after we | 441 // progress, but nothing really prevents this method to be called after we |
| 418 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this | 442 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this |
| 419 // point because we need the state machine for that (and even if we are really | 443 // point because we need the state machine for that (and even if we are really |
| 420 // free, that would be an asynchronous operation). In other words, keep the | 444 // free, that would be an asynchronous operation). In other words, keep the |
| 421 // entry how it is (it will be marked as truncated at destruction), and let | 445 // entry how it is (it will be marked as truncated at destruction), and let |
| 422 // the next piece of code that executes know that we are now reading directly | 446 // the next piece of code that executes know that we are now reading directly |
| 423 // from the net. | 447 // from the net. |
| 424 // TODO(mmenke): This doesn't release the lock on the cache entry, so a | 448 // TODO(mmenke): This doesn't release the lock on the cache entry, so a |
| 425 // future request for the resource will be blocked on this one. | 449 // future request for the resource will be blocked on this one. |
| 426 // Fix this. | 450 // Fix this. |
| 427 if (cache_.get() && entry_ && (mode_ & WRITE) && network_trans_.get() && | 451 if (shared_) { |
| 428 !is_sparse_ && !range_requested_) { | 452 // This might or might not stop caching based on whether other consumers |
| 453 // exist for this resource or not. If it does, shared_ will be set to false. | |
| 454 network_trans_ = cache_->StopCachingSharedWriters(this, entry_); | |
| 455 } | |
| 456 if (!shared_ && cache_.get() && entry_ && (mode_ & WRITE) && | |
| 457 network_trans_.get() && !is_sparse_ && !range_requested_) { | |
| 429 mode_ = NONE; | 458 mode_ = NONE; |
| 430 } | 459 } |
| 431 } | 460 } |
| 432 | 461 |
| 433 bool HttpCache::Transaction::GetFullRequestHeaders( | 462 bool HttpCache::Transaction::GetFullRequestHeaders( |
| 434 HttpRequestHeaders* headers) const { | 463 HttpRequestHeaders* headers) const { |
| 435 if (network_trans_) | 464 if (network_trans_) |
| 436 return network_trans_->GetFullRequestHeaders(headers); | 465 return network_trans_->GetFullRequestHeaders(headers); |
| 437 | 466 else if (shared_) { |
| 467 return entry_->shared_writers->GetFullRequestHeaders(headers); | |
| 468 } else if (have_full_request_headers_) { | |
| 469 *headers = full_request_headers_; | |
| 470 return true; | |
| 471 } | |
| 438 // TODO(juliatuttle): Read headers from cache. | 472 // TODO(juliatuttle): Read headers from cache. |
| 439 return false; | 473 return false; |
| 440 } | 474 } |
| 441 | 475 |
| 442 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const { | 476 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const { |
| 443 int64_t total_received_bytes = total_received_bytes_; | 477 int64_t total_received_bytes = total_received_bytes_; |
| 444 if (network_trans_) | 478 if (network_trans_) |
| 445 total_received_bytes += network_trans_->GetTotalReceivedBytes(); | 479 total_received_bytes += network_trans_->GetTotalReceivedBytes(); |
| 480 else if (shared_) { | |
| 481 total_received_bytes += entry_->shared_writers->GetTotalReceivedBytes(); | |
| 482 } | |
| 446 return total_received_bytes; | 483 return total_received_bytes; |
| 447 } | 484 } |
| 448 | 485 |
| 449 int64_t HttpCache::Transaction::GetTotalSentBytes() const { | 486 int64_t HttpCache::Transaction::GetTotalSentBytes() const { |
| 450 int64_t total_sent_bytes = total_sent_bytes_; | 487 int64_t total_sent_bytes = total_sent_bytes_; |
| 451 if (network_trans_) | 488 if (network_trans_) |
| 452 total_sent_bytes += network_trans_->GetTotalSentBytes(); | 489 total_sent_bytes += network_trans_->GetTotalSentBytes(); |
| 490 else if (shared_) { | |
| 491 total_sent_bytes += entry_->shared_writers->GetTotalSentBytes(); | |
| 492 } | |
| 453 return total_sent_bytes; | 493 return total_sent_bytes; |
| 454 } | 494 } |
| 455 | 495 |
| 456 void HttpCache::Transaction::DoneReading() { | 496 void HttpCache::Transaction::DoneReading() { |
| 457 if (cache_.get() && entry_) { | 497 if (cache_.get() && entry_) { |
| 458 DCHECK_NE(mode_, UPDATE); | 498 DCHECK_NE(mode_, UPDATE); |
| 499 bool perform_entry_cleanup = true; | |
| 500 if (shared_) { | |
| 501 cache_->DoneReadingSharedWriters(this, entry_); | |
| 502 // entry_ cleanup already performed, if any. | |
| 503 perform_entry_cleanup = false; | |
| 504 } | |
| 459 if (mode_ & WRITE) { | 505 if (mode_ & WRITE) { |
| 460 DoneWritingToEntry(true); | 506 DoneWritingToEntry(true, perform_entry_cleanup); |
| 461 } else if (mode_ & READ) { | 507 } else if (mode_ & READ) { |
| 462 // It is necessary to check mode_ & READ because it is possible | 508 // It is necessary to check mode_ & READ because it is possible |
| 463 // for mode_ to be NONE and entry_ non-NULL with a write entry | 509 // for mode_ to be NONE and entry_ non-NULL with a write entry |
| 464 // if StopCaching was called. | 510 // if StopCaching was called. |
| 465 cache_->DoneReadingFromEntry(entry_, this); | 511 cache_->DoneReadingFromEntry(entry_, this); |
| 466 entry_ = NULL; | 512 entry_ = NULL; |
| 467 } | 513 } |
| 468 } | 514 } |
| 469 } | 515 } |
| 470 | 516 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 491 return LOAD_STATE_IDLE; | 537 return LOAD_STATE_IDLE; |
| 492 } | 538 } |
| 493 | 539 |
| 494 void HttpCache::Transaction::SetQuicServerInfo( | 540 void HttpCache::Transaction::SetQuicServerInfo( |
| 495 QuicServerInfo* quic_server_info) {} | 541 QuicServerInfo* quic_server_info) {} |
| 496 | 542 |
| 497 bool HttpCache::Transaction::GetLoadTimingInfo( | 543 bool HttpCache::Transaction::GetLoadTimingInfo( |
| 498 LoadTimingInfo* load_timing_info) const { | 544 LoadTimingInfo* load_timing_info) const { |
| 499 if (network_trans_) | 545 if (network_trans_) |
| 500 return network_trans_->GetLoadTimingInfo(load_timing_info); | 546 return network_trans_->GetLoadTimingInfo(load_timing_info); |
| 547 else if (shared_) | |
| 548 return entry_->shared_writers->GetLoadTimingInfo(load_timing_info); | |
| 501 | 549 |
| 502 if (old_network_trans_load_timing_) { | 550 if (old_network_trans_load_timing_) { |
| 503 *load_timing_info = *old_network_trans_load_timing_; | 551 *load_timing_info = *old_network_trans_load_timing_; |
| 504 return true; | 552 return true; |
| 505 } | 553 } |
| 506 | 554 |
| 507 if (first_cache_access_since_.is_null()) | 555 if (first_cache_access_since_.is_null()) |
| 508 return false; | 556 return false; |
| 509 | 557 |
| 510 // If the cache entry was opened, return that time. | 558 // If the cache entry was opened, return that time. |
| 511 load_timing_info->send_start = first_cache_access_since_; | 559 load_timing_info->send_start = first_cache_access_since_; |
| 512 // This time doesn't make much sense when reading from the cache, so just use | 560 // This time doesn't make much sense when reading from the cache, so just use |
| 513 // the same time as send_start. | 561 // the same time as send_start. |
| 514 load_timing_info->send_end = first_cache_access_since_; | 562 load_timing_info->send_end = first_cache_access_since_; |
| 515 return true; | 563 return true; |
| 516 } | 564 } |
| 517 | 565 |
| 518 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { | 566 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { |
| 519 if (network_trans_) | 567 if (network_trans_) |
| 520 return network_trans_->GetRemoteEndpoint(endpoint); | 568 return network_trans_->GetRemoteEndpoint(endpoint); |
| 569 else if (shared_) | |
| 570 return entry_->shared_writers->GetRemoteEndpoint(endpoint); | |
| 521 | 571 |
| 522 if (!old_remote_endpoint_.address().empty()) { | 572 if (!old_remote_endpoint_.address().empty()) { |
| 523 *endpoint = old_remote_endpoint_; | 573 *endpoint = old_remote_endpoint_; |
| 524 return true; | 574 return true; |
| 525 } | 575 } |
| 526 | 576 |
| 527 return false; | 577 return false; |
| 528 } | 578 } |
| 529 | 579 |
| 530 void HttpCache::Transaction::PopulateNetErrorDetails( | 580 void HttpCache::Transaction::PopulateNetErrorDetails( |
| 531 NetErrorDetails* details) const { | 581 NetErrorDetails* details) const { |
| 532 if (network_trans_) | 582 if (network_trans_) |
| 533 return network_trans_->PopulateNetErrorDetails(details); | 583 return network_trans_->PopulateNetErrorDetails(details); |
| 584 else if (shared_) | |
| 585 return entry_->shared_writers->PopulateNetErrorDetails(details); | |
| 534 return; | 586 return; |
| 535 } | 587 } |
| 536 | 588 |
| 537 void HttpCache::Transaction::SetPriority(RequestPriority priority) { | 589 void HttpCache::Transaction::SetPriority(RequestPriority priority) { |
| 538 priority_ = priority; | 590 priority_ = priority; |
| 539 if (network_trans_) | 591 if (network_trans_) |
| 540 network_trans_->SetPriority(priority_); | 592 network_trans_->SetPriority(priority_); |
| 593 else if (shared_) | |
| 594 return entry_->shared_writers->SetPriority(priority_); | |
| 541 } | 595 } |
| 542 | 596 |
| 543 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( | 597 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( |
| 544 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { | 598 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { |
| 545 websocket_handshake_stream_base_create_helper_ = create_helper; | 599 websocket_handshake_stream_base_create_helper_ = create_helper; |
| 546 if (network_trans_) | 600 if (network_trans_) |
| 547 network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper); | 601 network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper); |
| 602 else if (shared_) { | |
| 603 return entry_->shared_writers->SetWebSocketHandshakeStreamCreateHelper( | |
| 604 create_helper); | |
| 605 } | |
| 548 } | 606 } |
| 549 | 607 |
| 550 void HttpCache::Transaction::SetBeforeNetworkStartCallback( | 608 void HttpCache::Transaction::SetBeforeNetworkStartCallback( |
| 551 const BeforeNetworkStartCallback& callback) { | 609 const BeforeNetworkStartCallback& callback) { |
| 552 DCHECK(!network_trans_); | 610 DCHECK(!network_trans_); |
| 553 before_network_start_callback_ = callback; | 611 before_network_start_callback_ = callback; |
| 554 } | 612 } |
| 555 | 613 |
| 556 void HttpCache::Transaction::SetBeforeHeadersSentCallback( | 614 void HttpCache::Transaction::SetBeforeHeadersSentCallback( |
| 557 const BeforeHeadersSentCallback& callback) { | 615 const BeforeHeadersSentCallback& callback) { |
| 558 DCHECK(!network_trans_); | 616 DCHECK(!network_trans_); |
| 559 before_headers_sent_callback_ = callback; | 617 before_headers_sent_callback_ = callback; |
| 560 } | 618 } |
| 561 | 619 |
| 562 int HttpCache::Transaction::ResumeNetworkStart() { | 620 int HttpCache::Transaction::ResumeNetworkStart() { |
| 563 if (network_trans_) | 621 if (network_trans_) |
| 564 return network_trans_->ResumeNetworkStart(); | 622 return network_trans_->ResumeNetworkStart(); |
| 623 else if (shared_) | |
| 624 return entry_->shared_writers->ResumeNetworkStart(); | |
| 565 return ERR_UNEXPECTED; | 625 return ERR_UNEXPECTED; |
| 566 } | 626 } |
| 567 | 627 |
| 568 void HttpCache::Transaction::GetConnectionAttempts( | 628 void HttpCache::Transaction::GetConnectionAttempts( |
| 569 ConnectionAttempts* out) const { | 629 ConnectionAttempts* out) const { |
| 570 ConnectionAttempts new_connection_attempts; | 630 ConnectionAttempts new_connection_attempts; |
| 571 if (network_trans_) | 631 if (network_trans_) |
| 572 network_trans_->GetConnectionAttempts(&new_connection_attempts); | 632 network_trans_->GetConnectionAttempts(&new_connection_attempts); |
| 633 else if (shared_) { | |
| 634 entry_->shared_writers->GetConnectionAttempts(&new_connection_attempts); | |
| 635 } | |
| 573 | 636 |
| 574 out->swap(new_connection_attempts); | 637 out->swap(new_connection_attempts); |
| 575 out->insert(out->begin(), old_connection_attempts_.begin(), | 638 out->insert(out->begin(), old_connection_attempts_.begin(), |
| 576 old_connection_attempts_.end()); | 639 old_connection_attempts_.end()); |
| 577 } | 640 } |
| 578 | 641 |
| 579 //----------------------------------------------------------------------------- | 642 //----------------------------------------------------------------------------- |
| 580 | 643 |
| 581 // A few common patterns: (Foo* means Foo -> FooComplete) | 644 // A few common patterns: (Foo* means Foo -> FooComplete) |
|
jkarlin
2016/12/06 18:08:18
Need to update this comment with a typical flow th
| |
| 582 // | 645 // |
| 583 // 1. Not-cached entry: | 646 // 1. Not-cached entry: |
| 584 // Start(): | 647 // Start(): |
| 585 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> | 648 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> |
| 586 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> | 649 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> |
| 587 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> | 650 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> |
| 588 // PartialHeadersReceived | 651 // PartialHeadersReceived |
| 589 // | 652 // |
| 590 // Read(): | 653 // Read(): |
| 591 // NetworkRead* -> CacheWriteData* | 654 // NetworkRead* -> CacheWriteData* |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 845 case STATE_CACHE_READ_METADATA_COMPLETE: | 908 case STATE_CACHE_READ_METADATA_COMPLETE: |
| 846 rv = DoCacheReadMetadataComplete(rv); | 909 rv = DoCacheReadMetadataComplete(rv); |
| 847 break; | 910 break; |
| 848 case STATE_NETWORK_READ: | 911 case STATE_NETWORK_READ: |
| 849 DCHECK_EQ(OK, rv); | 912 DCHECK_EQ(OK, rv); |
| 850 rv = DoNetworkRead(); | 913 rv = DoNetworkRead(); |
| 851 break; | 914 break; |
| 852 case STATE_NETWORK_READ_COMPLETE: | 915 case STATE_NETWORK_READ_COMPLETE: |
| 853 rv = DoNetworkReadComplete(rv); | 916 rv = DoNetworkReadComplete(rv); |
| 854 break; | 917 break; |
| 918 case STATE_SHARED_NETWORK_READ: | |
| 919 DCHECK_EQ(OK, rv); | |
| 920 rv = DoSharedNetworkRead(); | |
| 921 break; | |
| 922 case STATE_SHARED_NETWORK_READ_COMPLETE: | |
| 923 rv = DoSharedNetworkReadComplete(rv); | |
| 924 break; | |
| 925 case STATE_SHARED_NETWORK_READ_WAIT_COMPLETE: | |
| 926 rv = DoSharedNetworkReadWaitComplete(rv); | |
| 927 break; | |
| 855 case STATE_CACHE_READ_DATA: | 928 case STATE_CACHE_READ_DATA: |
| 856 DCHECK_EQ(OK, rv); | 929 DCHECK_EQ(OK, rv); |
| 857 rv = DoCacheReadData(); | 930 rv = DoCacheReadData(); |
| 858 break; | 931 break; |
| 859 case STATE_CACHE_READ_DATA_COMPLETE: | 932 case STATE_CACHE_READ_DATA_COMPLETE: |
| 860 rv = DoCacheReadDataComplete(rv); | 933 rv = DoCacheReadDataComplete(rv); |
| 861 break; | 934 break; |
| 862 case STATE_CACHE_WRITE_DATA: | 935 case STATE_CACHE_WRITE_DATA: |
| 863 rv = DoCacheWriteData(rv); | 936 rv = DoCacheWriteData(rv); |
| 864 break; | 937 break; |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1501 | 1574 |
| 1502 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); | 1575 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); |
| 1503 | 1576 |
| 1504 if (new_response_->headers->response_code() == 416 && | 1577 if (new_response_->headers->response_code() == 416 && |
| 1505 (request_->method == "GET" || request_->method == "POST")) { | 1578 (request_->method == "GET" || request_->method == "POST")) { |
| 1506 // If there is an active entry it may be destroyed with this transaction. | 1579 // If there is an active entry it may be destroyed with this transaction. |
| 1507 SetResponse(*new_response_); | 1580 SetResponse(*new_response_); |
| 1508 return OK; | 1581 return OK; |
| 1509 } | 1582 } |
| 1510 | 1583 |
| 1584 // If the transaction is shared and it is a 200 or an error response, then | |
| 1585 // doom the entry and let this transaction continue without writing to the | |
| 1586 // cache if shared writers contain more transactions. If not, continue | |
| 1587 // writing to the cache and also transfer the network transaction to shared | |
| 1588 // writers. | |
| 1589 if (shared_ && new_response->headers->response_code() != 304) { | |
| 1590 network_trans_ = cache_->ValidationNoMatchSharedWriters( | |
| 1591 cache_key_, this, std::move(network_trans_), priority_, entry_); | |
| 1592 if (!shared_) { | |
| 1593 DCHECK(network_trans_); | |
| 1594 if (cache_entry_status_ == CacheEntryStatus::ENTRY_UNDEFINED) { | |
| 1595 UpdateCacheEntryStatus( | |
| 1596 CacheEntryStatus::ENTRY_VALIDATED_DOOM_SHARED_WRITING); | |
| 1597 } | |
| 1598 DoneWritingToEntry(false, false); | |
| 1599 return OK; | |
| 1600 } else { | |
| 1601 DCHECK(!network_trans_); | |
| 1602 } | |
| 1603 } | |
| 1604 | |
| 1511 // Are we expecting a response to a conditional query? | 1605 // Are we expecting a response to a conditional query? |
| 1512 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 1606 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
| 1513 if (new_response->headers->response_code() == 304 || handling_206_) { | 1607 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 1514 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); | 1608 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); |
| 1515 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 1609 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
| 1516 return OK; | 1610 return OK; |
| 1517 } | 1611 } |
| 1518 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); | 1612 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); |
| 1519 mode_ = WRITE; | 1613 mode_ = WRITE; |
| 1520 } | 1614 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1646 | 1740 |
| 1647 int HttpCache::Transaction::DoCacheWriteResponse() { | 1741 int HttpCache::Transaction::DoCacheWriteResponse() { |
| 1648 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); | 1742 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); |
| 1649 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; | 1743 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; |
| 1650 return WriteResponseInfoToEntry(truncated_); | 1744 return WriteResponseInfoToEntry(truncated_); |
| 1651 } | 1745 } |
| 1652 | 1746 |
| 1653 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { | 1747 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { |
| 1654 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); | 1748 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); |
| 1655 next_state_ = STATE_TRUNCATE_CACHED_DATA; | 1749 next_state_ = STATE_TRUNCATE_CACHED_DATA; |
| 1656 return OnWriteResponseInfoToEntryComplete(result); | 1750 int res = OnWriteResponseInfoToEntryComplete(result); |
| 1751 | |
| 1752 if (res != OK) | |
| 1753 return result; | |
| 1754 | |
| 1755 return OK; | |
| 1756 } | |
| 1757 | |
| 1758 void HttpCache::Transaction::ResetShared(bool continue_network_reading, | |
| 1759 bool continue_cache_reading) { | |
| 1760 if (!continue_network_reading) { | |
| 1761 SaveSharedNetworkTransInfo(); | |
| 1762 } | |
| 1763 if (continue_cache_reading) { | |
| 1764 mode_ = READ; | |
| 1765 } | |
| 1766 shared_ = false; | |
| 1767 } | |
| 1768 | |
| 1769 void HttpCache::Transaction::SetFinalizeDoomed() { | |
| 1770 finalize_doomed_ = true; | |
| 1771 } | |
| 1772 | |
| 1773 void HttpCache::Transaction::SetShared() { | |
| 1774 shared_ = true; | |
| 1775 } | |
| 1776 | |
| 1777 bool HttpCache::Transaction::shared() const { | |
| 1778 return shared_; | |
| 1779 } | |
| 1780 | |
| 1781 bool HttpCache::Transaction::validating_shared() const { | |
| 1782 return shared_ && next_state_ != STATE_NONE && | |
| 1783 next_state_ <= STATE_START_STATE_MACHINE_FINAL; | |
| 1657 } | 1784 } |
| 1658 | 1785 |
| 1659 int HttpCache::Transaction::DoTruncateCachedData() { | 1786 int HttpCache::Transaction::DoTruncateCachedData() { |
| 1660 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); | 1787 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); |
| 1661 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; | 1788 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; |
| 1662 if (!entry_) | 1789 if (!entry_) |
| 1663 return OK; | 1790 return OK; |
| 1664 if (net_log_.IsCapturing()) | 1791 if (net_log_.IsCapturing()) |
| 1665 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); | 1792 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); |
| 1666 // Truncate the stream. | 1793 // Truncate the stream. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1697 if (net_log_.IsCapturing()) { | 1824 if (net_log_.IsCapturing()) { |
| 1698 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, | 1825 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, |
| 1699 result); | 1826 result); |
| 1700 } | 1827 } |
| 1701 } | 1828 } |
| 1702 | 1829 |
| 1703 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1830 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1704 return OK; | 1831 return OK; |
| 1705 } | 1832 } |
| 1706 | 1833 |
| 1834 void HttpCache::Transaction::ProcessForSharedWriting() { | |
| 1835 // Should not be already reading. | |
| 1836 if (reading_) | |
| 1837 return; | |
| 1838 | |
| 1839 // If not already part of SharedWriters, then check if one should be | |
| 1840 // created. | |
| 1841 if (!shared_ && !IsEligibleForSharedWriting()) | |
| 1842 return; | |
| 1843 | |
| 1844 if (shared_) { | |
| 1845 // Non 304 case is already handled in DoSuccessfulSendRequest. | |
| 1846 if (response_.headers->response_code() != 304) { | |
| 1847 return; | |
| 1848 } | |
| 1849 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED_DO_SHARED_WRITING); | |
| 1850 cache_->ValidationMatchSharedWriters(this, priority_, entry_); | |
| 1851 network_trans_.reset(); | |
| 1852 return; | |
| 1853 } | |
| 1854 | |
| 1855 // Do not create a SharedWriters if its a Redirect response. | |
| 1856 if (response_.headers->response_code() != 200) | |
| 1857 return; | |
| 1858 | |
| 1859 // or if its a no-store response. | |
| 1860 if (!entry_) | |
| 1861 return; | |
| 1862 | |
| 1863 DCHECK(entry_ && network_trans_); | |
| 1864 cache_->CreateSharedWriters(this, std::move(network_trans_), priority_); | |
| 1865 } | |
| 1866 | |
| 1707 int HttpCache::Transaction::DoPartialHeadersReceived() { | 1867 int HttpCache::Transaction::DoPartialHeadersReceived() { |
| 1708 new_response_ = NULL; | 1868 new_response_ = NULL; |
| 1709 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1869 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 1710 next_state_ = STATE_CACHE_READ_METADATA; | 1870 next_state_ = STATE_CACHE_READ_METADATA; |
| 1711 | 1871 |
| 1872 ProcessForSharedWriting(); | |
| 1873 | |
| 1712 if (!partial_) | 1874 if (!partial_) |
| 1713 return OK; | 1875 return OK; |
| 1714 | 1876 |
| 1715 if (reading_) { | 1877 if (reading_) { |
| 1716 if (network_trans_.get()) { | 1878 if (network_trans_.get()) { |
| 1717 next_state_ = STATE_NETWORK_READ; | 1879 next_state_ = STATE_NETWORK_READ; |
| 1718 } else { | 1880 } else { |
| 1719 next_state_ = STATE_CACHE_READ_DATA; | 1881 next_state_ = STATE_CACHE_READ_DATA; |
| 1720 } | 1882 } |
| 1721 } else if (mode_ != NONE) { | 1883 } else if (mode_ != NONE) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1747 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, | 1909 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, |
| 1748 result); | 1910 result); |
| 1749 if (result != response_.metadata->size()) | 1911 if (result != response_.metadata->size()) |
| 1750 return OnCacheReadError(result, false); | 1912 return OnCacheReadError(result, false); |
| 1751 return OK; | 1913 return OK; |
| 1752 } | 1914 } |
| 1753 | 1915 |
| 1754 int HttpCache::Transaction::DoNetworkRead() { | 1916 int HttpCache::Transaction::DoNetworkRead() { |
| 1755 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); | 1917 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); |
| 1756 next_state_ = STATE_NETWORK_READ_COMPLETE; | 1918 next_state_ = STATE_NETWORK_READ_COMPLETE; |
| 1919 | |
| 1757 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); | 1920 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); |
| 1758 } | 1921 } |
| 1759 | 1922 |
| 1760 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 1923 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| 1761 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); | 1924 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); |
| 1762 DCHECK(mode_ & WRITE || mode_ == NONE); | 1925 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 1763 | 1926 |
| 1764 if (!cache_.get()) | 1927 if (!cache_.get()) |
| 1765 return ERR_UNEXPECTED; | 1928 return ERR_UNEXPECTED; |
| 1766 | 1929 |
| 1767 // If there is an error or we aren't saving the data, we are done; just wait | 1930 // If there is an error or we aren't saving the data, we are done; just wait |
| 1768 // until the destructor runs to see if we can keep the data. | 1931 // until the destructor runs to see if we can keep the data. |
| 1769 if (mode_ == NONE || result < 0) | 1932 if (mode_ == NONE || result < 0) |
| 1770 return result; | 1933 return result; |
| 1771 | 1934 |
| 1772 next_state_ = STATE_CACHE_WRITE_DATA; | 1935 next_state_ = STATE_CACHE_WRITE_DATA; |
| 1773 return result; | 1936 return result; |
| 1774 } | 1937 } |
| 1775 | 1938 |
| 1939 int HttpCache::Transaction::DoSharedNetworkRead() { | |
| 1940 next_state_ = STATE_SHARED_NETWORK_READ_COMPLETE; | |
| 1941 bool shared_read_in_progress = false; | |
| 1942 int result = | |
| 1943 entry_->shared_writers->Read(read_buf_.get(), io_buf_len_, io_callback_, | |
| 1944 this, shared_read_in_progress); | |
| 1945 if (shared_read_in_progress) { | |
| 1946 next_state_ = STATE_SHARED_NETWORK_READ_WAIT_COMPLETE; | |
| 1947 } | |
| 1948 return result; | |
| 1949 } | |
| 1950 | |
| 1951 int HttpCache::Transaction::DoSharedNetworkReadComplete(int result) { | |
| 1952 if (result < 0) { | |
| 1953 cache_->NetworkReadFailedSharedWriters(this, entry_, result); | |
| 1954 | |
| 1955 // Set entry as null so that the destructor does not invoke DoneWithEntry | |
| 1956 // again as we have already processed the entry_ in | |
| 1957 // NetworkReadFailedSharedWriters | |
| 1958 entry_ = nullptr; | |
| 1959 return result; | |
| 1960 } | |
| 1961 | |
| 1962 read_offset_ += result; | |
| 1963 entry_->shared_writers->OnNetworkReadSuccess(this, read_buf_, result); | |
| 1964 | |
| 1965 next_state_ = STATE_CACHE_WRITE_DATA; | |
| 1966 return result; | |
| 1967 } | |
| 1968 | |
| 1969 int HttpCache::Transaction::DoSharedNetworkReadWaitComplete(int result) { | |
| 1970 // If its a network read failure, we just return the result. | |
| 1971 // If its a cache write failure, we return the result which is filled as -1 | |
| 1972 // by SharedWriters, | |
| 1973 // If its a cache write success, read_buf_ would have been filled | |
| 1974 // with the read data by SharedWriters, so just return from here. | |
| 1975 | |
| 1976 if (result == 0) { // response is complete. | |
| 1977 DoneWritingToEntry(true, false); // changes the mode_ to NONE. | |
| 1978 } else if (result > 0) { | |
| 1979 read_offset_ += result; | |
| 1980 } else { | |
| 1981 // Set entry as null so that the destructor does not invoke DoneWithEntry | |
| 1982 // again as we have already processed the entry_ in | |
| 1983 // NetworkReadFailedSharedWriters | |
| 1984 entry_ = nullptr; | |
| 1985 } | |
| 1986 | |
| 1987 return result; | |
| 1988 } | |
| 1989 | |
| 1776 int HttpCache::Transaction::DoCacheReadData() { | 1990 int HttpCache::Transaction::DoCacheReadData() { |
| 1777 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); | 1991 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); |
| 1778 if (request_->method == "HEAD") | 1992 if (request_->method == "HEAD") |
| 1779 return 0; | 1993 return 0; |
| 1780 | 1994 |
| 1781 DCHECK(entry_); | 1995 DCHECK(entry_); |
| 1782 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; | 1996 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; |
| 1783 | 1997 |
| 1784 if (net_log_.IsCapturing()) | 1998 if (net_log_.IsCapturing()) |
| 1785 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); | 1999 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1845 if (net_log_.IsCapturing()) { | 2059 if (net_log_.IsCapturing()) { |
| 1846 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, | 2060 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, |
| 1847 result); | 2061 result); |
| 1848 } | 2062 } |
| 1849 } | 2063 } |
| 1850 if (!cache_.get()) | 2064 if (!cache_.get()) |
| 1851 return ERR_UNEXPECTED; | 2065 return ERR_UNEXPECTED; |
| 1852 | 2066 |
| 1853 if (result != write_len_) { | 2067 if (result != write_len_) { |
| 1854 DLOG(ERROR) << "failed to write response data to cache"; | 2068 DLOG(ERROR) << "failed to write response data to cache"; |
| 1855 DoneWritingToEntry(false); | 2069 if (shared_) { |
| 2070 // Fail any shared writers. | |
| 2071 network_trans_.reset(cache_->CacheWriteFailedSharedWriters(this, entry_)); | |
| 2072 DCHECK(network_trans_); | |
| 2073 DoneWritingToEntry(false, false); | |
| 2074 } else { | |
| 2075 DoneWritingToEntry(false); | |
| 2076 } | |
| 1856 | 2077 |
| 1857 // We want to ignore errors writing to disk and just keep reading from | 2078 // We want to ignore errors writing to disk and just keep reading from |
| 1858 // the network. | 2079 // the network. |
| 1859 result = write_len_; | 2080 result = write_len_; |
| 1860 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) { | 2081 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) { |
| 1861 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2082 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1862 int64_t body_size = response_.headers->GetContentLength(); | 2083 int64_t body_size = response_.headers->GetContentLength(); |
| 1863 if (body_size >= 0 && body_size <= current_size) | 2084 if (body_size >= 0 && body_size <= current_size) |
| 1864 done_reading_ = true; | 2085 done_reading_ = true; |
| 1865 } | 2086 } |
| 1866 | 2087 |
| 1867 if (partial_) { | 2088 if (partial_) { |
| 1868 // This may be the last request. | 2089 // This may be the last request. |
| 1869 if (result != 0 || truncated_ || | 2090 if (result != 0 || truncated_ || |
| 1870 !(partial_->IsLastRange() || mode_ == WRITE)) { | 2091 !(partial_->IsLastRange() || mode_ == WRITE)) { |
| 1871 return DoPartialNetworkReadCompleted(result); | 2092 return DoPartialNetworkReadCompleted(result); |
| 1872 } | 2093 } |
| 1873 } | 2094 } |
| 1874 | 2095 |
| 2096 bool complete = false; | |
| 1875 if (result == 0) { | 2097 if (result == 0) { |
| 1876 // End of file. This may be the result of a connection problem so see if we | 2098 // End of file. This may be the result of a connection problem so see if we |
| 1877 // have to keep the entry around to be flagged as truncated later on. | 2099 // have to keep the entry around to be flagged as truncated later on. |
| 1878 if (done_reading_ || !entry_ || partial_ || | 2100 if (done_reading_ || !entry_ || partial_ || |
| 1879 response_.headers->GetContentLength() <= 0) { | 2101 response_.headers->GetContentLength() <= 0) { |
| 1880 DoneWritingToEntry(true); | 2102 complete = true; |
| 1881 } | 2103 } |
| 1882 } | 2104 } |
| 1883 | 2105 |
| 2106 bool perform_entry_cleanup = true; | |
| 2107 if (shared_) { | |
| 2108 if (result || (!result && complete)) { | |
| 2109 cache_->CacheWriteSuccessSharedWriters(this, entry_, result); | |
| 2110 // entry_ cleanup already performed, if any. | |
| 2111 perform_entry_cleanup = false; | |
| 2112 } | |
| 2113 } | |
| 2114 if (complete) { | |
| 2115 DoneWritingToEntry(true, perform_entry_cleanup); | |
| 2116 } | |
| 2117 | |
| 1884 return result; | 2118 return result; |
| 1885 } | 2119 } |
| 1886 | 2120 |
| 1887 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { | 2121 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { |
| 1888 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); | 2122 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); |
| 1889 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; | 2123 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; |
| 1890 return WriteResponseInfoToEntry(true); | 2124 return WriteResponseInfoToEntry(true); |
| 1891 } | 2125 } |
| 1892 | 2126 |
| 1893 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { | 2127 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2082 | 2316 |
| 2083 if (partial_ && (is_sparse_ || truncated_) && | 2317 if (partial_ && (is_sparse_ || truncated_) && |
| 2084 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 2318 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
| 2085 // Force revalidation for sparse or truncated entries. Note that we don't | 2319 // Force revalidation for sparse or truncated entries. Note that we don't |
| 2086 // want to ignore the regular validation logic just because a byte range was | 2320 // want to ignore the regular validation logic just because a byte range was |
| 2087 // part of the request. | 2321 // part of the request. |
| 2088 skip_validation = false; | 2322 skip_validation = false; |
| 2089 } | 2323 } |
| 2090 | 2324 |
| 2091 if (skip_validation) { | 2325 if (skip_validation) { |
| 2092 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); | 2326 if (shared_) { |
| 2093 return SetupEntryForRead(); | 2327 UpdateCacheEntryStatus( |
| 2328 CacheEntryStatus::ENTRY_SKIP_VALIDATION_DO_SHARED_WRITING); | |
| 2329 entry_->shared_writers->OnValidationMatch(this, priority_); | |
| 2330 } else { | |
| 2331 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); | |
| 2332 return SetupEntryForRead(); | |
| 2333 } | |
| 2094 } else { | 2334 } else { |
| 2095 // Make the network request conditional, to see if we may reuse our cached | 2335 // Make the network request conditional, to see if we may reuse our cached |
| 2096 // response. If we cannot do so, then we just resort to a normal fetch. | 2336 // response. If we cannot do so, then we just resort to a normal fetch. |
| 2097 // Our mode remains READ_WRITE for a conditional request. Even if the | 2337 // Our mode remains READ_WRITE for a conditional request. Even if the |
| 2098 // conditionalization fails, we don't switch to WRITE mode until we | 2338 // conditionalization fails, we don't switch to WRITE mode until we |
| 2099 // know we won't be falling back to using the cache entry in the | 2339 // know we won't be falling back to using the cache entry in the |
| 2100 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2340 // LOAD_FROM_CACHE_IF_OFFLINE case. |
| 2101 if (!ConditionalizeRequest()) { | 2341 if (!ConditionalizeRequest()) { |
| 2102 couldnt_conditionalize_request_ = true; | 2342 couldnt_conditionalize_request_ = true; |
| 2103 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); | 2343 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2234 DCHECK(network_trans_.get()); | 2474 DCHECK(network_trans_.get()); |
| 2235 DCHECK_EQ(STATE_NONE, next_state_); | 2475 DCHECK_EQ(STATE_NONE, next_state_); |
| 2236 | 2476 |
| 2237 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 2477 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
| 2238 int rv = network_trans_->RestartWithAuth(credentials, io_callback_); | 2478 int rv = network_trans_->RestartWithAuth(credentials, io_callback_); |
| 2239 if (rv != ERR_IO_PENDING) | 2479 if (rv != ERR_IO_PENDING) |
| 2240 return DoLoop(rv); | 2480 return DoLoop(rv); |
| 2241 return rv; | 2481 return rv; |
| 2242 } | 2482 } |
| 2243 | 2483 |
| 2484 void HttpCache::Transaction::Orphan(std::unique_ptr<HttpTransaction> trans) { | |
| 2485 DCHECK_EQ(trans.get(), this); | |
| 2486 orphaned_ = true; | |
| 2487 | |
| 2488 // Reset consumer's callback. | |
| 2489 callback_.Reset(); | |
| 2490 | |
| 2491 if (shared_) { | |
| 2492 if (next_state_ == STATE_SHARED_NETWORK_READ_COMPLETE || | |
| 2493 next_state_ == STATE_CACHE_WRITE_DATA_COMPLETE) { | |
| 2494 // Might lead to setting shared_ to false if this is the only transaction | |
| 2495 // in SharedWriters. | |
| 2496 cache_->DoomCurrentSharedWriter(std::move(trans), entry_); | |
| 2497 } else if (next_state_ == STATE_SHARED_NETWORK_READ_WAIT_COMPLETE) { | |
| 2498 entry_->shared_writers->RemoveWaitingWriter(this); | |
| 2499 } else if (next_state_ != STATE_NONE && | |
| 2500 next_state_ <= STATE_ADD_TO_ENTRY_COMPLETE) { | |
| 2501 cache_->RemovePendingTransaction(this); | |
| 2502 // Set cache_pending_ to false so that more cleanup is not attempted in | |
| 2503 // the destructor. | |
| 2504 cache_pending_ = false; | |
| 2505 } else if (validating_shared()) { | |
| 2506 cache_->RemoveValidatingTransSharedWriters(this, entry_); | |
| 2507 } else { | |
| 2508 bool cancel_request = reading_ && response_.headers.get(); | |
| 2509 if (cancel_request) { | |
| 2510 cancel_request &= (response_.headers->response_code() == 200); | |
| 2511 } | |
| 2512 cache_->RemoveIdleSharedWriter(this, entry_, cancel_request); | |
| 2513 } | |
| 2514 | |
| 2515 if (!shared_) { | |
| 2516 // Since any cleanup needed in entry_ and shared_writers is already done, | |
| 2517 // set entry_ to null. | |
| 2518 entry_ = nullptr; | |
| 2519 } | |
| 2520 } | |
| 2521 | |
| 2522 if (!shared_) { | |
| 2523 trans.reset(); | |
| 2524 } | |
| 2525 } | |
| 2526 | |
| 2244 ValidationType HttpCache::Transaction::RequiresValidation() { | 2527 ValidationType HttpCache::Transaction::RequiresValidation() { |
| 2245 // TODO(darin): need to do more work here: | 2528 // TODO(darin): need to do more work here: |
| 2246 // - make sure we have a matching request method | 2529 // - make sure we have a matching request method |
| 2247 // - watch out for cached responses that depend on authentication | 2530 // - watch out for cached responses that depend on authentication |
| 2248 | 2531 |
| 2249 if (response_.vary_data.is_valid() && | 2532 if (response_.vary_data.is_valid() && |
| 2250 !response_.vary_data.MatchesRequest(*request_, | 2533 !response_.vary_data.MatchesRequest(*request_, |
| 2251 *response_.headers.get())) { | 2534 *response_.headers.get())) { |
| 2252 vary_mismatch_ = true; | 2535 vary_mismatch_ = true; |
| 2253 validation_cause_ = VALIDATION_CAUSE_VARY_MISMATCH; | 2536 validation_cause_ = VALIDATION_CAUSE_VARY_MISMATCH; |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2566 } | 2849 } |
| 2567 | 2850 |
| 2568 int HttpCache::Transaction::WriteToEntry(int index, int offset, | 2851 int HttpCache::Transaction::WriteToEntry(int index, int offset, |
| 2569 IOBuffer* data, int data_len, | 2852 IOBuffer* data, int data_len, |
| 2570 const CompletionCallback& callback) { | 2853 const CompletionCallback& callback) { |
| 2571 if (!entry_) | 2854 if (!entry_) |
| 2572 return data_len; | 2855 return data_len; |
| 2573 | 2856 |
| 2574 int rv = 0; | 2857 int rv = 0; |
| 2575 if (!partial_ || !data_len) { | 2858 if (!partial_ || !data_len) { |
| 2576 rv = entry_->disk_entry->WriteData(index, offset, data, data_len, callback, | 2859 CompletionCallback io_callback = callback; |
| 2577 true); | 2860 |
| 2861 rv = entry_->disk_entry->WriteData(index, offset, data, data_len, | |
| 2862 io_callback, true); | |
| 2578 } else { | 2863 } else { |
| 2579 rv = partial_->CacheWrite(entry_->disk_entry, data, data_len, callback); | 2864 rv = partial_->CacheWrite(entry_->disk_entry, data, data_len, callback); |
| 2580 } | 2865 } |
| 2581 return rv; | 2866 return rv; |
| 2582 } | 2867 } |
| 2583 | 2868 |
| 2584 int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) { | 2869 int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) { |
| 2585 if (!entry_) | 2870 if (!entry_) |
| 2586 return OK; | 2871 return OK; |
| 2587 | 2872 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2627 result); | 2912 result); |
| 2628 } | 2913 } |
| 2629 | 2914 |
| 2630 if (result != io_buf_len_) { | 2915 if (result != io_buf_len_) { |
| 2631 DLOG(ERROR) << "failed to write response info to cache"; | 2916 DLOG(ERROR) << "failed to write response info to cache"; |
| 2632 DoneWritingToEntry(false); | 2917 DoneWritingToEntry(false); |
| 2633 } | 2918 } |
| 2634 return OK; | 2919 return OK; |
| 2635 } | 2920 } |
| 2636 | 2921 |
| 2637 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2922 void HttpCache::Transaction::DoneWritingToEntry(bool success, |
| 2923 bool perform_entry_cleanup) { | |
| 2638 if (!entry_) | 2924 if (!entry_) |
| 2639 return; | 2925 return; |
| 2640 | 2926 |
| 2641 RecordHistograms(); | 2927 RecordHistograms(); |
| 2642 | 2928 |
| 2643 cache_->DoneWritingToEntry(entry_, success); | 2929 if (perform_entry_cleanup) { |
| 2644 entry_ = NULL; | 2930 cache_->DoneWritingToEntry(entry_, success); |
| 2931 } | |
| 2932 entry_ = nullptr; | |
| 2645 mode_ = NONE; // switch to 'pass through' mode | 2933 mode_ = NONE; // switch to 'pass through' mode |
| 2646 } | 2934 } |
| 2647 | 2935 |
| 2936 void HttpCache::Transaction::ContinueWithoutSharedWriting() { | |
| 2937 // Should own a network transaction to continue. | |
| 2938 DCHECK(network_trans_); | |
| 2939 shared_ = false; | |
| 2940 entry_ = nullptr; | |
| 2941 mode_ = NONE; | |
| 2942 } | |
| 2943 | |
| 2648 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2944 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
| 2649 DLOG(ERROR) << "ReadData failed: " << result; | 2945 DLOG(ERROR) << "ReadData failed: " << result; |
| 2650 const int result_for_histogram = std::max(0, -result); | 2946 const int result_for_histogram = std::max(0, -result); |
| 2651 if (restart) { | 2947 if (restart) { |
| 2652 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", | 2948 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", |
| 2653 result_for_histogram); | 2949 result_for_histogram); |
| 2654 } else { | 2950 } else { |
| 2655 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", | 2951 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", |
| 2656 result_for_histogram); | 2952 result_for_histogram); |
| 2657 } | 2953 } |
| 2658 | 2954 |
| 2659 // Avoid using this entry in the future. | 2955 // Avoid using this entry in the future. |
| 2660 if (cache_.get()) | 2956 if (cache_.get()) |
| 2661 cache_->DoomActiveEntry(cache_key_); | 2957 cache_->DoomActiveEntry(cache_key_); |
| 2662 | 2958 |
| 2663 if (restart) { | 2959 if (restart) { |
| 2664 DCHECK(!reading_); | 2960 DCHECK(!reading_); |
| 2665 DCHECK(!network_trans_.get()); | 2961 DCHECK(!network_trans_.get()); |
| 2666 cache_->DoneWithEntry(entry_, this, false); | 2962 if (shared_) { |
| 2963 cache_->RemoveValidatingTransSharedWriters(this, entry_); | |
| 2964 } else { | |
| 2965 cache_->DoneWithEntry(entry_, this, false); | |
| 2966 } | |
| 2667 entry_ = NULL; | 2967 entry_ = NULL; |
| 2668 is_sparse_ = false; | 2968 is_sparse_ = false; |
| 2669 partial_.reset(); | 2969 partial_.reset(); |
| 2670 next_state_ = STATE_GET_BACKEND; | 2970 next_state_ = STATE_GET_BACKEND; |
| 2671 return OK; | 2971 return OK; |
| 2672 } | 2972 } |
| 2673 | 2973 |
| 2674 return ERR_CACHE_READ_FAILURE; | 2974 return ERR_CACHE_READ_FAILURE; |
| 2675 } | 2975 } |
| 2676 | 2976 |
| 2677 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { | 2977 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { |
| 2678 if (entry_lock_waiting_since_ != start_time) | 2978 if (entry_lock_waiting_since_ != start_time) |
| 2679 return; | 2979 return; |
| 2680 | 2980 |
| 2681 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); | 2981 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); |
| 2682 | 2982 |
| 2683 if (!cache_) | 2983 if (!cache_) |
| 2684 return; | 2984 return; |
| 2685 | 2985 |
| 2686 cache_->RemovePendingTransaction(this); | 2986 cache_->RemovePendingTransaction(this); |
| 2687 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); | 2987 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); |
| 2688 } | 2988 } |
| 2689 | 2989 |
| 2690 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { | 2990 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { |
| 2991 // Partial requests not supported with shared writing as of now. | |
| 2992 DCHECK(!shared_); | |
| 2691 DVLOG(2) << "DoomPartialEntry"; | 2993 DVLOG(2) << "DoomPartialEntry"; |
| 2692 int rv = cache_->DoomEntry(cache_key_, NULL); | 2994 int rv = cache_->DoomEntry(cache_key_, NULL); |
| 2693 DCHECK_EQ(OK, rv); | 2995 DCHECK_EQ(OK, rv); |
| 2694 cache_->DoneWithEntry(entry_, this, false); | 2996 cache_->DoneWithEntry(entry_, this, false); |
| 2695 entry_ = NULL; | 2997 entry_ = NULL; |
| 2696 is_sparse_ = false; | 2998 is_sparse_ = false; |
| 2697 truncated_ = false; | 2999 truncated_ = false; |
| 2698 if (delete_object) | 3000 if (delete_object) |
| 2699 partial_.reset(NULL); | 3001 partial_.reset(NULL); |
| 2700 } | 3002 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2741 if (!delete_object) { | 3043 if (!delete_object) { |
| 2742 // The simplest way to re-initialize partial_ is to create a new object. | 3044 // The simplest way to re-initialize partial_ is to create a new object. |
| 2743 partial_.reset(new PartialData()); | 3045 partial_.reset(new PartialData()); |
| 2744 if (partial_->Init(request_->extra_headers)) | 3046 if (partial_->Init(request_->extra_headers)) |
| 2745 partial_->SetHeaders(custom_request_->extra_headers); | 3047 partial_->SetHeaders(custom_request_->extra_headers); |
| 2746 else | 3048 else |
| 2747 partial_.reset(); | 3049 partial_.reset(); |
| 2748 } | 3050 } |
| 2749 } | 3051 } |
| 2750 | 3052 |
| 2751 void HttpCache::Transaction::ResetNetworkTransaction() { | 3053 void HttpCache::Transaction::SaveNetworkTransInfo() { |
| 2752 DCHECK(!old_network_trans_load_timing_); | 3054 DCHECK(!old_network_trans_load_timing_); |
| 2753 DCHECK(network_trans_); | 3055 DCHECK(network_trans_); |
| 2754 LoadTimingInfo load_timing; | 3056 LoadTimingInfo load_timing; |
| 2755 if (network_trans_->GetLoadTimingInfo(&load_timing)) | 3057 if (network_trans_->GetLoadTimingInfo(&load_timing)) |
| 2756 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); | 3058 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); |
| 2757 total_received_bytes_ += network_trans_->GetTotalReceivedBytes(); | 3059 total_received_bytes_ += network_trans_->GetTotalReceivedBytes(); |
| 2758 total_sent_bytes_ += network_trans_->GetTotalSentBytes(); | 3060 total_sent_bytes_ += network_trans_->GetTotalSentBytes(); |
| 2759 ConnectionAttempts attempts; | 3061 ConnectionAttempts attempts; |
| 2760 network_trans_->GetConnectionAttempts(&attempts); | 3062 network_trans_->GetConnectionAttempts(&attempts); |
| 2761 for (const auto& attempt : attempts) | 3063 for (const auto& attempt : attempts) |
| 2762 old_connection_attempts_.push_back(attempt); | 3064 old_connection_attempts_.push_back(attempt); |
| 2763 old_remote_endpoint_ = IPEndPoint(); | 3065 old_remote_endpoint_ = IPEndPoint(); |
| 2764 network_trans_->GetRemoteEndpoint(&old_remote_endpoint_); | 3066 network_trans_->GetRemoteEndpoint(&old_remote_endpoint_); |
| 3067 } | |
| 3068 | |
| 3069 void HttpCache::Transaction::SaveSharedNetworkTransInfo() { | |
| 3070 // If network_trans_ is still present, this transaction has not started using | |
| 3071 // the "shared" network transaction, so do nothing. | |
| 3072 if (network_trans_) | |
| 3073 return; | |
| 3074 DCHECK(!old_network_trans_load_timing_); | |
| 3075 | |
| 3076 // If the transaction is being deleted while still in the waiting queue, | |
| 3077 // entry_ is not yet set, do nothing. | |
| 3078 if (!entry_) | |
| 3079 return; | |
| 3080 DCHECK(entry_->shared_writers); | |
| 3081 LoadTimingInfo load_timing; | |
| 3082 if (entry_->shared_writers->GetLoadTimingInfo(&load_timing)) | |
| 3083 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); | |
| 3084 total_received_bytes_ += entry_->shared_writers->GetTotalReceivedBytes(); | |
| 3085 total_sent_bytes_ += entry_->shared_writers->GetTotalSentBytes(); | |
| 3086 ConnectionAttempts attempts; | |
| 3087 entry_->shared_writers->GetConnectionAttempts(&attempts); | |
| 3088 for (const auto& attempt : attempts) | |
| 3089 old_connection_attempts_.push_back(attempt); | |
| 3090 old_remote_endpoint_ = IPEndPoint(); | |
| 3091 entry_->shared_writers->GetRemoteEndpoint(&old_remote_endpoint_); | |
| 3092 have_full_request_headers_ = | |
| 3093 entry_->shared_writers->GetFullRequestHeaders(&full_request_headers_); | |
| 3094 } | |
| 3095 | |
| 3096 void HttpCache::Transaction::ResetNetworkTransaction() { | |
| 3097 SaveNetworkTransInfo(); | |
| 2765 network_trans_.reset(); | 3098 network_trans_.reset(); |
| 2766 } | 3099 } |
| 2767 | 3100 |
| 2768 // Histogram data from the end of 2010 show the following distribution of | 3101 // Histogram data from the end of 2010 show the following distribution of |
| 2769 // response headers: | 3102 // response headers: |
| 2770 // | 3103 // |
| 2771 // Content-Length............... 87% | 3104 // Content-Length............... 87% |
| 2772 // Date......................... 98% | 3105 // Date......................... 98% |
| 2773 // Last-Modified................ 49% | 3106 // Last-Modified................ 49% |
| 2774 // Etag......................... 19% | 3107 // Etag......................... 19% |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2922 | 3255 |
| 2923 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) | 3256 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) |
| 2924 return; | 3257 return; |
| 2925 DCHECK(!range_requested_); | 3258 DCHECK(!range_requested_); |
| 2926 DCHECK(!first_cache_access_since_.is_null()); | 3259 DCHECK(!first_cache_access_since_.is_null()); |
| 2927 | 3260 |
| 2928 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; | 3261 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2929 | 3262 |
| 2930 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); | 3263 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2931 | 3264 |
| 3265 if (cache_entry_status_ == | |
| 3266 CacheEntryStatus::ENTRY_VALIDATED_DO_SHARED_WRITING) { | |
| 3267 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.ValidationMatchSharedWriting", | |
| 3268 total_time); | |
| 3269 } | |
| 3270 | |
| 2932 bool did_send_request = !send_request_since_.is_null(); | 3271 bool did_send_request = !send_request_since_.is_null(); |
| 2933 DCHECK( | 3272 DCHECK((did_send_request && |
| 2934 (did_send_request && | 3273 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || |
| 2935 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || | 3274 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || |
| 2936 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || | 3275 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || |
| 2937 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || | 3276 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE || |
| 2938 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE)) || | 3277 cache_entry_status_ == |
| 2939 (!did_send_request && | 3278 CacheEntryStatus::ENTRY_VALIDATED_DO_SHARED_WRITING || |
| 2940 cache_entry_status_ == CacheEntryStatus::ENTRY_USED)); | 3279 cache_entry_status_ == |
| 3280 CacheEntryStatus::ENTRY_VALIDATED_DOOM_SHARED_WRITING)) || | |
| 3281 (!did_send_request && | |
| 3282 (cache_entry_status_ == CacheEntryStatus::ENTRY_USED || | |
| 3283 cache_entry_status_ == | |
| 3284 CacheEntryStatus::ENTRY_SKIP_VALIDATION_DO_SHARED_WRITING))); | |
| 2941 | 3285 |
| 2942 if (!did_send_request) { | 3286 if (!did_send_request) { |
| 2943 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_USED); | 3287 if (cache_entry_status_ == CacheEntryStatus::ENTRY_USED) { |
| 2944 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); | 3288 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); |
| 3289 } else if (cache_entry_status_ == | |
| 3290 CacheEntryStatus::ENTRY_SKIP_VALIDATION_DO_SHARED_WRITING) { | |
| 3291 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SkipValidationSharedWriting", | |
| 3292 total_time); | |
| 3293 } | |
| 2945 return; | 3294 return; |
| 2946 } | 3295 } |
| 2947 | 3296 |
| 2948 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; | 3297 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; |
| 2949 int64_t before_send_percent = (total_time.ToInternalValue() == 0) | 3298 int64_t before_send_percent = (total_time.ToInternalValue() == 0) |
| 2950 ? 0 | 3299 ? 0 |
| 2951 : before_send_time * 100 / total_time; | 3300 : before_send_time * 100 / total_time; |
| 2952 DCHECK_GE(before_send_percent, 0); | 3301 DCHECK_GE(before_send_percent, 0); |
| 2953 DCHECK_LE(before_send_percent, 100); | 3302 DCHECK_LE(before_send_percent, 100); |
| 2954 base::HistogramBase::Sample before_send_sample = | 3303 base::HistogramBase::Sample before_send_sample = |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2979 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", | 3328 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", |
| 2980 before_send_sample); | 3329 before_send_sample); |
| 2981 break; | 3330 break; |
| 2982 } | 3331 } |
| 2983 case CacheEntryStatus::ENTRY_UPDATED: { | 3332 case CacheEntryStatus::ENTRY_UPDATED: { |
| 2984 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); | 3333 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); |
| 2985 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", | 3334 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", |
| 2986 before_send_sample); | 3335 before_send_sample); |
| 2987 break; | 3336 break; |
| 2988 } | 3337 } |
| 3338 case CacheEntryStatus::ENTRY_VALIDATED_DO_SHARED_WRITING: { | |
| 3339 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.ValidationMatchSharedWriting", | |
| 3340 before_send_time); | |
| 3341 UMA_HISTOGRAM_PERCENTAGE( | |
| 3342 "HttpCache.PercentBeforeSend.ValidationMatchSharedWriting", | |
| 3343 before_send_sample); | |
| 3344 break; | |
| 3345 } | |
| 3346 case CacheEntryStatus::ENTRY_VALIDATED_DOOM_SHARED_WRITING: { | |
| 3347 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.ValidationDoomSharedWriting", | |
| 3348 before_send_time); | |
| 3349 UMA_HISTOGRAM_PERCENTAGE( | |
| 3350 "HttpCache.PercentBeforeSend.ValidationDoomSharedWriting", | |
| 3351 before_send_sample); | |
| 3352 break; | |
| 3353 } | |
| 2989 default: | 3354 default: |
| 2990 NOTREACHED(); | 3355 NOTREACHED(); |
| 2991 } | 3356 } |
| 2992 } | 3357 } |
| 2993 | 3358 |
| 3359 bool HttpCache::Transaction::IsEligibleForSharedWriting() const { | |
| 3360 if (!(mode_ & WRITE)) | |
| 3361 return false; | |
| 3362 | |
| 3363 DCHECK(request_); | |
| 3364 if (request_->method != "GET") | |
| 3365 return false; | |
| 3366 | |
| 3367 if (partial_ || range_requested_) | |
| 3368 return false; | |
| 3369 | |
| 3370 return true; | |
| 3371 } | |
| 3372 | |
| 3373 void HttpCache::Transaction::SetSharedWritingFailState() { | |
| 3374 // This state should only be set when the transaction is idle waiting for Read | |
| 3375 // to be invoked. | |
| 3376 DCHECK_EQ(next_state_, STATE_NONE); | |
| 3377 next_state_ = STATE_SHARED_READ_WRITE_FAILED; | |
| 3378 entry_ = nullptr; | |
| 3379 } | |
| 3380 | |
| 2994 void HttpCache::Transaction::OnIOComplete(int result) { | 3381 void HttpCache::Transaction::OnIOComplete(int result) { |
| 3382 // Setting this in a local variable because if the consumer still exists, its | |
| 3383 // possible for this object to get destroyed during the consumer's callback | |
| 3384 // processing. | |
| 3385 bool orphaned = orphaned_; | |
| 2995 DoLoop(result); | 3386 DoLoop(result); |
| 3387 if (orphaned && finalize_doomed_) { | |
|
jkarlin
2016/12/06 21:06:28
finalized_doomed_ should cause a crash if this obj
shivanisha
2016/12/06 21:53:35
The underlying assumption here is that since orpha
jkarlin
2016/12/07 01:09:04
Makes sense, thanks.
| |
| 3388 cache_->FinalizeDoomedSharedWriter(entry_); | |
|
jkarlin
2016/12/06 21:06:28
Also entry_
shivanisha
2016/12/06 21:53:35
Same as above.
shivanisha
2016/12/07 00:09:02
For clarity, I will add a comment for this assumpt
| |
| 3389 } | |
| 2996 } | 3390 } |
| 2997 | 3391 |
| 2998 } // namespace net | 3392 } // namespace net |
| OLD | NEW |