| 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 } | 189 } |
| 190 | 190 |
| 191 HttpCache::Transaction::~Transaction() { | 191 HttpCache::Transaction::~Transaction() { |
| 192 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); | 192 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); |
| 193 // We may have to issue another IO, but we should never invoke the callback_ | 193 // We may have to issue another IO, but we should never invoke the callback_ |
| 194 // after this point. | 194 // after this point. |
| 195 callback_.Reset(); | 195 callback_.Reset(); |
| 196 | 196 |
| 197 if (cache_) { | 197 if (cache_) { |
| 198 if (entry_) { | 198 if (entry_) { |
| 199 bool cancel_request = reading_ && response_.headers.get(); | 199 cache_->DoneWithEntry(entry_, this, true /* process_cancel */, |
| 200 if (cancel_request) { | 200 partial_ != nullptr); |
| 201 if (partial_) { | |
| 202 entry_->disk_entry->CancelSparseIO(); | |
| 203 } else { | |
| 204 cancel_request &= (response_.headers->response_code() == 200); | |
| 205 } | |
| 206 } | |
| 207 | |
| 208 cache_->DoneWithEntry(entry_, this, cancel_request); | |
| 209 } else if (cache_pending_) { | 201 } else if (cache_pending_) { |
| 210 cache_->RemovePendingTransaction(this); | 202 cache_->RemovePendingTransaction(this); |
| 211 } | 203 } |
| 212 } | 204 } |
| 213 } | 205 } |
| 214 | 206 |
| 215 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, | 207 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, |
| 216 const CompletionCallback& callback) { | 208 const CompletionCallback& callback) { |
| 217 DCHECK(buf); | 209 DCHECK(buf); |
| 218 DCHECK_GT(buf_len, 0); | 210 DCHECK_GT(buf_len, 0); |
| 219 DCHECK(!callback.is_null()); | 211 DCHECK(!callback.is_null()); |
| 220 if (!cache_.get() || !entry_) | 212 if (!cache_.get() || !entry_) |
| 221 return ERR_UNEXPECTED; | 213 return ERR_UNEXPECTED; |
| 222 | 214 |
| 223 // We don't need to track this operation for anything. | 215 // We don't need to track this operation for anything. |
| 224 // It could be possible to check if there is something already written and | 216 // It could be possible to check if there is something already written and |
| 225 // avoid writing again (it should be the same, right?), but let's allow the | 217 // avoid writing again (it should be the same, right?), but let's allow the |
| 226 // caller to "update" the contents with something new. | 218 // caller to "update" the contents with something new. |
| 227 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, | 219 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, |
| 228 callback, true); | 220 callback, true); |
| 229 } | 221 } |
| 230 | 222 |
| 231 bool HttpCache::Transaction::AddTruncatedFlag() { | 223 bool HttpCache::Transaction::AddTruncatedFlag(bool* did_truncate) { |
| 224 *did_truncate = false; |
| 232 DCHECK(mode_ & WRITE || mode_ == NONE); | 225 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 233 | 226 |
| 234 // Don't set the flag for sparse entries. | 227 // Don't set the flag for sparse entries. |
| 235 if (partial_ && !truncated_) | 228 if (partial_ && !truncated_) |
| 236 return true; | 229 return true; |
| 237 | 230 |
| 238 if (!CanResume(true)) | 231 if (!CanResume(true)) |
| 239 return false; | 232 return false; |
| 240 | 233 |
| 241 // We may have received the whole resource already. | 234 // We may have received the whole resource already. |
| 242 if (done_reading_) | 235 if (done_reading_) |
| 243 return true; | 236 return true; |
| 244 | 237 |
| 245 truncated_ = true; | 238 truncated_ = true; |
| 239 *did_truncate = truncated_; |
| 246 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; | 240 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; |
| 247 DoLoop(OK); | 241 DoLoop(OK); |
| 248 return true; | 242 return true; |
| 249 } | 243 } |
| 250 | 244 |
| 251 LoadState HttpCache::Transaction::GetWriterLoadState() const { | 245 LoadState HttpCache::Transaction::GetWriterLoadState() const { |
| 252 if (network_trans_.get()) | 246 if (network_trans_.get()) |
| 253 return network_trans_->GetLoadState(); | 247 return network_trans_->GetLoadState(); |
| 254 if (entry_ || !request_) | 248 if (entry_ || !request_) |
| 255 return LOAD_STATE_IDLE; | 249 return LOAD_STATE_IDLE; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 | 397 |
| 404 void HttpCache::Transaction::StopCaching() { | 398 void HttpCache::Transaction::StopCaching() { |
| 405 // We really don't know where we are now. Hopefully there is no operation in | 399 // We really don't know where we are now. Hopefully there is no operation in |
| 406 // progress, but nothing really prevents this method to be called after we | 400 // progress, but nothing really prevents this method to be called after we |
| 407 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this | 401 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this |
| 408 // point because we need the state machine for that (and even if we are really | 402 // point because we need the state machine for that (and even if we are really |
| 409 // free, that would be an asynchronous operation). In other words, keep the | 403 // free, that would be an asynchronous operation). In other words, keep the |
| 410 // entry how it is (it will be marked as truncated at destruction), and let | 404 // entry how it is (it will be marked as truncated at destruction), and let |
| 411 // the next piece of code that executes know that we are now reading directly | 405 // the next piece of code that executes know that we are now reading directly |
| 412 // from the net. | 406 // from the net. |
| 413 // TODO(mmenke): This doesn't release the lock on the cache entry, so a | |
| 414 // future request for the resource will be blocked on this one. | |
| 415 // Fix this. | |
| 416 if (cache_.get() && entry_ && (mode_ & WRITE) && network_trans_.get() && | 407 if (cache_.get() && entry_ && (mode_ & WRITE) && network_trans_.get() && |
| 417 !is_sparse_ && !range_requested_) { | 408 !is_sparse_ && !range_requested_) { |
| 418 mode_ = NONE; | 409 mode_ = NONE; |
| 410 |
| 411 // Let entry_ know so that any dependent transactions are restarted and this |
| 412 // entry is doomed. |
| 413 cache_->DoneWritingToEntry(entry_, false /* success */, this); |
| 414 entry_ = nullptr; |
| 419 } | 415 } |
| 420 } | 416 } |
| 421 | 417 |
| 422 bool HttpCache::Transaction::GetFullRequestHeaders( | 418 bool HttpCache::Transaction::GetFullRequestHeaders( |
| 423 HttpRequestHeaders* headers) const { | 419 HttpRequestHeaders* headers) const { |
| 424 if (network_trans_) | 420 if (network_trans_) |
| 425 return network_trans_->GetFullRequestHeaders(headers); | 421 return network_trans_->GetFullRequestHeaders(headers); |
| 426 | 422 |
| 427 // TODO(juliatuttle): Read headers from cache. | 423 // TODO(juliatuttle): Read headers from cache. |
| 428 return false; | 424 return false; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 444 | 440 |
| 445 void HttpCache::Transaction::DoneReading() { | 441 void HttpCache::Transaction::DoneReading() { |
| 446 if (cache_.get() && entry_) { | 442 if (cache_.get() && entry_) { |
| 447 DCHECK_NE(mode_, UPDATE); | 443 DCHECK_NE(mode_, UPDATE); |
| 448 if (mode_ & WRITE) { | 444 if (mode_ & WRITE) { |
| 449 DoneWritingToEntry(true); | 445 DoneWritingToEntry(true); |
| 450 } else if (mode_ & READ) { | 446 } else if (mode_ & READ) { |
| 451 // It is necessary to check mode_ & READ because it is possible | 447 // It is necessary to check mode_ & READ because it is possible |
| 452 // for mode_ to be NONE and entry_ non-NULL with a write entry | 448 // for mode_ to be NONE and entry_ non-NULL with a write entry |
| 453 // if StopCaching was called. | 449 // if StopCaching was called. |
| 454 cache_->DoneReadingFromEntry(entry_, this); | 450 cache_->DoneWithEntry(entry_, this, false /* process_cancel */, |
| 451 partial_ != nullptr); |
| 455 entry_ = NULL; | 452 entry_ = NULL; |
| 456 } | 453 } |
| 457 } | 454 } |
| 458 } | 455 } |
| 459 | 456 |
| 460 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const { | 457 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const { |
| 461 // Null headers means we encountered an error or haven't a response yet | 458 // Null headers means we encountered an error or haven't a response yet |
| 462 if (auth_response_.headers.get()) { | 459 if (auth_response_.headers.get()) { |
| 463 DCHECK_EQ(cache_entry_status_, auth_response_.cache_entry_status) | 460 DCHECK_EQ(cache_entry_status_, auth_response_.cache_entry_status) |
| 464 << "These must be in sync via SetResponse and SetAuthResponse."; | 461 << "These must be in sync via SetResponse and SetAuthResponse."; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 ConnectionAttempts* out) const { | 555 ConnectionAttempts* out) const { |
| 559 ConnectionAttempts new_connection_attempts; | 556 ConnectionAttempts new_connection_attempts; |
| 560 if (network_trans_) | 557 if (network_trans_) |
| 561 network_trans_->GetConnectionAttempts(&new_connection_attempts); | 558 network_trans_->GetConnectionAttempts(&new_connection_attempts); |
| 562 | 559 |
| 563 out->swap(new_connection_attempts); | 560 out->swap(new_connection_attempts); |
| 564 out->insert(out->begin(), old_connection_attempts_.begin(), | 561 out->insert(out->begin(), old_connection_attempts_.begin(), |
| 565 old_connection_attempts_.end()); | 562 old_connection_attempts_.end()); |
| 566 } | 563 } |
| 567 | 564 |
| 565 void HttpCache::Transaction::SetValidatingCannotProceed() { |
| 566 DCHECK(!reading_); |
| 567 // Ensure this transaction is waiting for a callback. |
| 568 DCHECK_NE(STATE_UNSET, next_state_); |
| 569 |
| 570 next_state_ = STATE_HEADERS_PHASE_CANNOT_PROCEED; |
| 571 entry_ = nullptr; |
| 572 } |
| 573 |
| 568 size_t HttpCache::Transaction::EstimateMemoryUsage() const { | 574 size_t HttpCache::Transaction::EstimateMemoryUsage() const { |
| 569 // TODO(xunjieli): Consider improving the coverage. crbug.com/669108. | 575 // TODO(xunjieli): Consider improving the coverage. crbug.com/669108. |
| 570 return 0; | 576 return 0; |
| 571 } | 577 } |
| 572 | 578 |
| 573 //----------------------------------------------------------------------------- | 579 //----------------------------------------------------------------------------- |
| 574 | 580 |
| 575 // A few common patterns: (Foo* means Foo -> FooComplete) | 581 // A few common patterns: (Foo* means Foo -> FooComplete) |
| 576 // | 582 // |
| 577 // 1. Not-cached entry: | 583 // 1. Not-cached entry: |
| 578 // Start(): | 584 // Start(): |
| 579 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> | 585 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> |
| 580 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> | 586 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> |
| 581 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> | 587 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> |
| 582 // PartialHeadersReceived | 588 // PartialHeadersReceived -> FinishHeaders* |
| 583 // | 589 // |
| 584 // Read(): | 590 // Read(): |
| 585 // NetworkRead* -> CacheWriteData* | 591 // NetworkRead* -> CacheWriteData* |
| 586 // | 592 // |
| 587 // 2. Cached entry, no validation: | 593 // 2. Cached entry, no validation: |
| 588 // Start(): | 594 // Start(): |
| 589 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 595 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 590 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 596 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 591 // BeginCacheValidation() -> SetupEntryForRead() | 597 // BeginCacheValidation() -> SetupEntryForRead() -> FinishHeaders* |
| 592 // | 598 // |
| 593 // Read(): | 599 // Read(): |
| 594 // CacheReadData* | 600 // CacheReadData* |
| 595 // | 601 // |
| 596 // 3. Cached entry, validation (304): | 602 // 3. Cached entry, validation (304): |
| 597 // Start(): | 603 // Start(): |
| 598 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 604 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 599 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 605 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 600 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 606 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 601 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> | 607 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> |
| 602 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> | 608 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> |
| 603 // PartialHeadersReceived | 609 // PartialHeadersReceived -> FinishHeaders* |
| 604 // | 610 // |
| 605 // Read(): | 611 // Read(): |
| 606 // CacheReadData* | 612 // CacheReadData* |
| 607 // | 613 // |
| 608 // 4. Cached entry, validation and replace (200): | 614 // 4. Cached entry, validation and replace (200): |
| 609 // Start(): | 615 // Start(): |
| 610 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 616 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 611 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 617 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 612 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 618 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 613 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> | 619 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> |
| 614 // TruncateCachedMetadata* -> PartialHeadersReceived | 620 // TruncateCachedMetadata* -> PartialHeadersReceived -> FinishHeaders* |
| 615 // | 621 // |
| 616 // Read(): | 622 // Read(): |
| 617 // NetworkRead* -> CacheWriteData* | 623 // NetworkRead* -> CacheWriteData* |
| 618 // | 624 // |
| 619 // 5. Sparse entry, partially cached, byte range request: | 625 // 5. Sparse entry, partially cached, byte range request: |
| 620 // Start(): | 626 // Start(): |
| 621 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 627 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 622 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 628 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 623 // CacheQueryData* -> ValidateEntryHeadersAndContinue() -> | 629 // CacheQueryData* -> ValidateEntryHeadersAndContinue() -> |
| 624 // StartPartialCacheValidation -> CompletePartialCacheValidation -> | 630 // StartPartialCacheValidation -> CompletePartialCacheValidation -> |
| 625 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 631 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 626 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> | 632 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> |
| 627 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> | 633 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> |
| 628 // PartialHeadersReceived | 634 // PartialHeadersReceived -> FinishHeaders* |
| 629 // | 635 // |
| 630 // Read() 1: | 636 // Read() 1: |
| 631 // NetworkRead* -> CacheWriteData* | 637 // NetworkRead* -> CacheWriteData* |
| 632 // | 638 // |
| 633 // Read() 2: | 639 // Read() 2: |
| 634 // NetworkRead* -> CacheWriteData* -> StartPartialCacheValidation -> | 640 // NetworkRead* -> CacheWriteData* -> StartPartialCacheValidation -> |
| 635 // CompletePartialCacheValidation -> CacheReadData* -> | 641 // CompletePartialCacheValidation -> CacheReadData* -> |
| 636 // | 642 // |
| 637 // Read() 3: | 643 // Read() 3: |
| 638 // CacheReadData* -> StartPartialCacheValidation -> | 644 // CacheReadData* -> StartPartialCacheValidation -> |
| (...skipping 20 matching lines...) Expand all Loading... |
| 659 // Read(): | 665 // Read(): |
| 660 // CacheReadData (returns 0) | 666 // CacheReadData (returns 0) |
| 661 // | 667 // |
| 662 // 9. HEAD. Cached entry, validation and replace (200): | 668 // 9. HEAD. Cached entry, validation and replace (200): |
| 663 // Pass through. The request dooms the old entry, as a HEAD won't be stored by | 669 // Pass through. The request dooms the old entry, as a HEAD won't be stored by |
| 664 // itself. | 670 // itself. |
| 665 // Start(): | 671 // Start(): |
| 666 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 672 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 667 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 673 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 668 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 674 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 669 // OverwriteCachedResponse | 675 // OverwriteCachedResponse -> FinishHeaders* |
| 670 // | 676 // |
| 671 // 10. HEAD. Sparse entry, partially cached: | 677 // 10. HEAD. Sparse entry, partially cached: |
| 672 // Serve the request from the cache, as long as it doesn't require | 678 // Serve the request from the cache, as long as it doesn't require |
| 673 // revalidation. Ignore missing ranges when deciding to revalidate. If the | 679 // revalidation. Ignore missing ranges when deciding to revalidate. If the |
| 674 // entry requires revalidation, ignore the whole request and go to full pass | 680 // entry requires revalidation, ignore the whole request and go to full pass |
| 675 // through (the result of the HEAD request will NOT update the entry). | 681 // through (the result of the HEAD request will NOT update the entry). |
| 676 // | 682 // |
| 677 // Start(): Basically the same as example 7, as we never create a partial_ | 683 // Start(): Basically the same as example 7, as we never create a partial_ |
| 678 // object for this request. | 684 // object for this request. |
| 679 // | 685 // |
| 680 // 11. Prefetch, not-cached entry: | 686 // 11. Prefetch, not-cached entry: |
| 681 // The same as example 1. The "unused_since_prefetch" bit is stored as true in | 687 // The same as example 1. The "unused_since_prefetch" bit is stored as true in |
| 682 // UpdateCachedResponse. | 688 // UpdateCachedResponse. |
| 683 // | 689 // |
| 684 // 12. Prefetch, cached entry: | 690 // 12. Prefetch, cached entry: |
| 685 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between | 691 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between |
| 686 // CacheReadResponse* and CacheDispatchValidation if the unused_since_prefetch | 692 // CacheReadResponse* and CacheDispatchValidation if the unused_since_prefetch |
| 687 // bit is unset. | 693 // bit is unset. |
| 688 // | 694 // |
| 689 // 13. Cached entry less than 5 minutes old, unused_since_prefetch is true: | 695 // 13. Cached entry less than 5 minutes old, unused_since_prefetch is true: |
| 690 // Skip validation, similar to example 2. | 696 // Skip validation, similar to example 2. |
| 691 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 697 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 692 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> | 698 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> |
| 693 // BeginPartialCacheValidation() -> BeginCacheValidation() -> | 699 // BeginPartialCacheValidation() -> BeginCacheValidation() -> |
| 694 // SetupEntryForRead() | 700 // SetupEntryForRead() -> FinishHeaders* |
| 695 // | 701 // |
| 696 // Read(): | 702 // Read(): |
| 697 // CacheReadData* | 703 // CacheReadData* |
| 698 // | 704 // |
| 699 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: | 705 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: |
| 700 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between | 706 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between |
| 701 // CacheReadResponse* and CacheDispatchValidation. | 707 // CacheReadResponse* and CacheDispatchValidation. |
| 702 int HttpCache::Transaction::DoLoop(int result) { | 708 int HttpCache::Transaction::DoLoop(int result) { |
| 703 DCHECK_NE(STATE_UNSET, next_state_); | 709 DCHECK_NE(STATE_UNSET, next_state_); |
| 704 DCHECK_NE(STATE_NONE, next_state_); | 710 DCHECK_NE(STATE_NONE, next_state_); |
| 705 DCHECK(!in_do_loop_); | 711 DCHECK(!in_do_loop_); |
| 706 | 712 |
| 707 int rv = result; | 713 int rv = result; |
| 714 State state = next_state_; |
| 708 do { | 715 do { |
| 709 State state = next_state_; | 716 state = next_state_; |
| 710 next_state_ = STATE_UNSET; | 717 next_state_ = STATE_UNSET; |
| 711 base::AutoReset<bool> scoped_in_do_loop(&in_do_loop_, true); | 718 base::AutoReset<bool> scoped_in_do_loop(&in_do_loop_, true); |
| 712 | 719 |
| 713 switch (state) { | 720 switch (state) { |
| 714 case STATE_GET_BACKEND: | 721 case STATE_GET_BACKEND: |
| 715 DCHECK_EQ(OK, rv); | 722 DCHECK_EQ(OK, rv); |
| 716 rv = DoGetBackend(); | 723 rv = DoGetBackend(); |
| 717 break; | 724 break; |
| 718 case STATE_GET_BACKEND_COMPLETE: | 725 case STATE_GET_BACKEND_COMPLETE: |
| 719 rv = DoGetBackendComplete(rv); | 726 rv = DoGetBackendComplete(rv); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 DCHECK_EQ(OK, rv); | 843 DCHECK_EQ(OK, rv); |
| 837 rv = DoPartialHeadersReceived(); | 844 rv = DoPartialHeadersReceived(); |
| 838 break; | 845 break; |
| 839 case STATE_CACHE_READ_METADATA: | 846 case STATE_CACHE_READ_METADATA: |
| 840 DCHECK_EQ(OK, rv); | 847 DCHECK_EQ(OK, rv); |
| 841 rv = DoCacheReadMetadata(); | 848 rv = DoCacheReadMetadata(); |
| 842 break; | 849 break; |
| 843 case STATE_CACHE_READ_METADATA_COMPLETE: | 850 case STATE_CACHE_READ_METADATA_COMPLETE: |
| 844 rv = DoCacheReadMetadataComplete(rv); | 851 rv = DoCacheReadMetadataComplete(rv); |
| 845 break; | 852 break; |
| 853 case STATE_HEADERS_PHASE_CANNOT_PROCEED: |
| 854 rv = DoHeadersPhaseCannotProceed(); |
| 855 break; |
| 856 case STATE_FINISH_HEADERS: |
| 857 rv = DoFinishHeaders(rv); |
| 858 break; |
| 859 case STATE_FINISH_HEADERS_COMPLETE: |
| 860 rv = DoFinishHeadersComplete(rv); |
| 861 break; |
| 846 case STATE_NETWORK_READ: | 862 case STATE_NETWORK_READ: |
| 847 DCHECK_EQ(OK, rv); | 863 DCHECK_EQ(OK, rv); |
| 848 rv = DoNetworkRead(); | 864 rv = DoNetworkRead(); |
| 849 break; | 865 break; |
| 850 case STATE_NETWORK_READ_COMPLETE: | 866 case STATE_NETWORK_READ_COMPLETE: |
| 851 rv = DoNetworkReadComplete(rv); | 867 rv = DoNetworkReadComplete(rv); |
| 852 break; | 868 break; |
| 853 case STATE_CACHE_READ_DATA: | 869 case STATE_CACHE_READ_DATA: |
| 854 DCHECK_EQ(OK, rv); | 870 DCHECK_EQ(OK, rv); |
| 855 rv = DoCacheReadData(); | 871 rv = DoCacheReadData(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 872 break; | 888 break; |
| 873 default: | 889 default: |
| 874 NOTREACHED() << "bad state " << state; | 890 NOTREACHED() << "bad state " << state; |
| 875 rv = ERR_FAILED; | 891 rv = ERR_FAILED; |
| 876 break; | 892 break; |
| 877 } | 893 } |
| 878 DCHECK(next_state_ != STATE_UNSET) << "Previous state was " << state; | 894 DCHECK(next_state_ != STATE_UNSET) << "Previous state was " << state; |
| 879 | 895 |
| 880 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 896 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| 881 | 897 |
| 898 // Assert Start() state machine's allowed last state in successful cases when |
| 899 // caching is happening. |
| 900 DCHECK(reading_ || rv != OK || !entry_ || |
| 901 state == STATE_FINISH_HEADERS_COMPLETE); |
| 902 |
| 882 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 903 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 883 read_buf_ = NULL; // Release the buffer before invoking the callback. | 904 read_buf_ = nullptr; // Release the buffer before invoking the callback. |
| 884 base::ResetAndReturn(&callback_).Run(rv); | 905 base::ResetAndReturn(&callback_).Run(rv); |
| 885 } | 906 } |
| 886 | 907 |
| 887 return rv; | 908 return rv; |
| 888 } | 909 } |
| 889 | 910 |
| 890 int HttpCache::Transaction::DoGetBackend() { | 911 int HttpCache::Transaction::DoGetBackend() { |
| 891 cache_pending_ = true; | 912 cache_pending_ = true; |
| 892 TransitionToState(STATE_GET_BACKEND_COMPLETE); | 913 TransitionToState(STATE_GET_BACKEND_COMPLETE); |
| 893 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND); | 914 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND); |
| 894 return cache_->GetBackendForTransaction(this); | 915 return cache_->GetBackendForTransaction(this); |
| 895 } | 916 } |
| 896 | 917 |
| 897 int HttpCache::Transaction::DoGetBackendComplete(int result) { | 918 int HttpCache::Transaction::DoGetBackendComplete(int result) { |
| 898 DCHECK(result == OK || result == ERR_FAILED); | 919 DCHECK(result == OK || result == ERR_FAILED); |
| 899 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_GET_BACKEND, | 920 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_GET_BACKEND, |
| 900 result); | 921 result); |
| 901 cache_pending_ = false; | 922 cache_pending_ = false; |
| 902 | 923 |
| 903 if (!ShouldPassThrough()) { | 924 if (!ShouldPassThrough()) { |
| 904 cache_key_ = cache_->GenerateCacheKey(request_); | 925 cache_key_ = cache_->GenerateCacheKey(request_); |
| 905 | 926 |
| 906 // Requested cache access mode. | 927 // Requested cache access mode. |
| 907 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { | 928 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { |
| 908 if (effective_load_flags_ & LOAD_BYPASS_CACHE) { | 929 if (effective_load_flags_ & LOAD_BYPASS_CACHE) { |
| 909 // The client has asked for nonsense. | 930 // The client has asked for nonsense. |
| 910 TransitionToState(STATE_NONE); | 931 TransitionToState(STATE_FINISH_HEADERS); |
| 911 return ERR_CACHE_MISS; | 932 return ERR_CACHE_MISS; |
| 912 } | 933 } |
| 913 mode_ = READ; | 934 mode_ = READ; |
| 914 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { | 935 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { |
| 915 mode_ = WRITE; | 936 mode_ = WRITE; |
| 916 } else { | 937 } else { |
| 917 mode_ = READ_WRITE; | 938 mode_ = READ_WRITE; |
| 918 } | 939 } |
| 919 | 940 |
| 920 // Downgrade to UPDATE if the request has been externally conditionalized. | 941 // Downgrade to UPDATE if the request has been externally conditionalized. |
| 921 if (external_validation_.initialized) { | 942 if (external_validation_.initialized) { |
| 922 if (mode_ & WRITE) { | 943 if (mode_ & WRITE) { |
| 923 // Strip off the READ_DATA bit (and maybe add back a READ_META bit | 944 // Strip off the READ_DATA bit (and maybe add back a READ_META bit |
| 924 // in case READ was off). | 945 // in case READ was off). |
| 925 mode_ = UPDATE; | 946 mode_ = UPDATE; |
| 926 } else { | 947 } else { |
| 927 mode_ = NONE; | 948 mode_ = NONE; |
| 928 } | 949 } |
| 929 } | 950 } |
| 930 } | 951 } |
| 931 | 952 |
| 932 // Use PUT and DELETE only to invalidate existing stored entries. | 953 // Use PUT and DELETE only to invalidate existing stored entries. |
| 933 if ((request_->method == "PUT" || request_->method == "DELETE") && | 954 if ((method_ == "PUT" || method_ == "DELETE") && mode_ != READ_WRITE && |
| 934 mode_ != READ_WRITE && mode_ != WRITE) { | 955 mode_ != WRITE) { |
| 935 mode_ = NONE; | 956 mode_ = NONE; |
| 936 } | 957 } |
| 937 | 958 |
| 938 // Note that if mode_ == UPDATE (which is tied to external_validation_), the | 959 // Note that if mode_ == UPDATE (which is tied to external_validation_), the |
| 939 // transaction behaves the same for GET and HEAD requests at this point: if it | 960 // transaction behaves the same for GET and HEAD requests at this point: if it |
| 940 // was not modified, the entry is updated and a response is not returned from | 961 // was not modified, the entry is updated and a response is not returned from |
| 941 // the cache. If we receive 200, it doesn't matter if there was a validation | 962 // the cache. If we receive 200, it doesn't matter if there was a validation |
| 942 // header or not. | 963 // header or not. |
| 943 if (request_->method == "HEAD" && mode_ == WRITE) | 964 if (method_ == "HEAD" && mode_ == WRITE) |
| 944 mode_ = NONE; | 965 mode_ = NONE; |
| 945 | 966 |
| 946 // If must use cache, then we must fail. This can happen for back/forward | 967 // If must use cache, then we must fail. This can happen for back/forward |
| 947 // navigations to a page generated via a form post. | 968 // navigations to a page generated via a form post. |
| 948 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { | 969 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { |
| 949 TransitionToState(STATE_NONE); | 970 TransitionToState(STATE_FINISH_HEADERS); |
| 950 return ERR_CACHE_MISS; | 971 return ERR_CACHE_MISS; |
| 951 } | 972 } |
| 952 | 973 |
| 953 if (mode_ == NONE) { | 974 if (mode_ == NONE) { |
| 954 if (partial_) { | 975 if (partial_) { |
| 955 partial_->RestoreHeaders(&custom_request_->extra_headers); | 976 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 956 partial_.reset(); | 977 partial_.reset(); |
| 957 } | 978 } |
| 958 TransitionToState(STATE_SEND_REQUEST); | 979 TransitionToState(STATE_SEND_REQUEST); |
| 959 } else { | 980 } else { |
| 960 TransitionToState(STATE_INIT_ENTRY); | 981 TransitionToState(STATE_INIT_ENTRY); |
| 961 } | 982 } |
| 962 | 983 |
| 963 // This is only set if we have something to do with the response. | 984 // This is only set if we have something to do with the response. |
| 964 range_requested_ = (partial_.get() != NULL); | 985 range_requested_ = (partial_.get() != NULL); |
| 965 | 986 |
| 987 // mode_ may change later, save the initial mode in case we need to restart |
| 988 // this request. |
| 989 restart_info_.mode = mode_; |
| 966 return OK; | 990 return OK; |
| 967 } | 991 } |
| 968 | 992 |
| 969 int HttpCache::Transaction::DoInitEntry() { | 993 int HttpCache::Transaction::DoInitEntry() { |
| 970 TRACE_EVENT0("io", "HttpCacheTransaction::DoInitEntry"); | 994 TRACE_EVENT0("io", "HttpCacheTransaction::DoInitEntry"); |
| 971 DCHECK(!new_entry_); | 995 DCHECK(!new_entry_); |
| 972 | 996 |
| 973 if (!cache_.get()) { | 997 if (!cache_.get()) { |
| 974 TransitionToState(STATE_NONE); | 998 TransitionToState(STATE_FINISH_HEADERS); |
| 975 return ERR_UNEXPECTED; | 999 return ERR_UNEXPECTED; |
| 976 } | 1000 } |
| 977 | 1001 |
| 978 if (mode_ == WRITE) { | 1002 if (mode_ == WRITE) { |
| 979 TransitionToState(STATE_DOOM_ENTRY); | 1003 TransitionToState(STATE_DOOM_ENTRY); |
| 980 return OK; | 1004 return OK; |
| 981 } | 1005 } |
| 982 | 1006 |
| 983 TransitionToState(STATE_OPEN_ENTRY); | 1007 TransitionToState(STATE_OPEN_ENTRY); |
| 984 return OK; | 1008 return OK; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1001 // transaction attached. | 1025 // transaction attached. |
| 1002 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_OPEN_ENTRY, | 1026 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_OPEN_ENTRY, |
| 1003 result); | 1027 result); |
| 1004 cache_pending_ = false; | 1028 cache_pending_ = false; |
| 1005 if (result == OK) { | 1029 if (result == OK) { |
| 1006 TransitionToState(STATE_ADD_TO_ENTRY); | 1030 TransitionToState(STATE_ADD_TO_ENTRY); |
| 1007 return OK; | 1031 return OK; |
| 1008 } | 1032 } |
| 1009 | 1033 |
| 1010 if (result == ERR_CACHE_RACE) { | 1034 if (result == ERR_CACHE_RACE) { |
| 1011 TransitionToState(STATE_INIT_ENTRY); | 1035 TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); |
| 1012 return OK; | 1036 return OK; |
| 1013 } | 1037 } |
| 1014 | 1038 |
| 1015 if (request_->method == "PUT" || request_->method == "DELETE" || | 1039 if (method_ == "PUT" || method_ == "DELETE" || |
| 1016 (request_->method == "HEAD" && mode_ == READ_WRITE)) { | 1040 (method_ == "HEAD" && mode_ == READ_WRITE)) { |
| 1017 DCHECK(mode_ == READ_WRITE || mode_ == WRITE || request_->method == "HEAD"); | 1041 DCHECK(mode_ == READ_WRITE || mode_ == WRITE || method_ == "HEAD"); |
| 1018 mode_ = NONE; | 1042 mode_ = NONE; |
| 1019 TransitionToState(STATE_SEND_REQUEST); | 1043 TransitionToState(STATE_SEND_REQUEST); |
| 1020 return OK; | 1044 return OK; |
| 1021 } | 1045 } |
| 1022 | 1046 |
| 1023 if (mode_ == READ_WRITE) { | 1047 if (mode_ == READ_WRITE) { |
| 1024 mode_ = WRITE; | 1048 mode_ = WRITE; |
| 1025 TransitionToState(STATE_CREATE_ENTRY); | 1049 TransitionToState(STATE_CREATE_ENTRY); |
| 1026 return OK; | 1050 return OK; |
| 1027 } | 1051 } |
| 1028 if (mode_ == UPDATE) { | 1052 if (mode_ == UPDATE) { |
| 1029 // There is no cache entry to update; proceed without caching. | 1053 // There is no cache entry to update; proceed without caching. |
| 1030 mode_ = NONE; | 1054 mode_ = NONE; |
| 1031 TransitionToState(STATE_SEND_REQUEST); | 1055 TransitionToState(STATE_SEND_REQUEST); |
| 1032 return OK; | 1056 return OK; |
| 1033 } | 1057 } |
| 1034 | 1058 |
| 1035 // The entry does not exist, and we are not permitted to create a new entry, | 1059 // The entry does not exist, and we are not permitted to create a new entry, |
| 1036 // so we must fail. | 1060 // so we must fail. |
| 1037 TransitionToState(STATE_NONE); | 1061 TransitionToState(STATE_FINISH_HEADERS); |
| 1038 return ERR_CACHE_MISS; | 1062 return ERR_CACHE_MISS; |
| 1039 } | 1063 } |
| 1040 | 1064 |
| 1041 int HttpCache::Transaction::DoDoomEntry() { | 1065 int HttpCache::Transaction::DoDoomEntry() { |
| 1042 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntry"); | 1066 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntry"); |
| 1043 TransitionToState(STATE_DOOM_ENTRY_COMPLETE); | 1067 TransitionToState(STATE_DOOM_ENTRY_COMPLETE); |
| 1044 cache_pending_ = true; | 1068 cache_pending_ = true; |
| 1045 if (first_cache_access_since_.is_null()) | 1069 if (first_cache_access_since_.is_null()) |
| 1046 first_cache_access_since_ = TimeTicks::Now(); | 1070 first_cache_access_since_ = TimeTicks::Now(); |
| 1047 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_DOOM_ENTRY); | 1071 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_DOOM_ENTRY); |
| 1048 return cache_->DoomEntry(cache_key_, this); | 1072 return cache_->DoomEntry(cache_key_, this); |
| 1049 } | 1073 } |
| 1050 | 1074 |
| 1051 int HttpCache::Transaction::DoDoomEntryComplete(int result) { | 1075 int HttpCache::Transaction::DoDoomEntryComplete(int result) { |
| 1052 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntryComplete"); | 1076 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntryComplete"); |
| 1053 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_DOOM_ENTRY, | 1077 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_DOOM_ENTRY, |
| 1054 result); | 1078 result); |
| 1055 cache_pending_ = false; | 1079 cache_pending_ = false; |
| 1056 TransitionToState(result == ERR_CACHE_RACE ? STATE_INIT_ENTRY | 1080 TransitionToState(result == ERR_CACHE_RACE |
| 1057 : STATE_CREATE_ENTRY); | 1081 ? STATE_HEADERS_PHASE_CANNOT_PROCEED |
| 1082 : STATE_CREATE_ENTRY); |
| 1058 return OK; | 1083 return OK; |
| 1059 } | 1084 } |
| 1060 | 1085 |
| 1061 int HttpCache::Transaction::DoCreateEntry() { | 1086 int HttpCache::Transaction::DoCreateEntry() { |
| 1062 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntry"); | 1087 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntry"); |
| 1063 DCHECK(!new_entry_); | 1088 DCHECK(!new_entry_); |
| 1064 TransitionToState(STATE_CREATE_ENTRY_COMPLETE); | 1089 TransitionToState(STATE_CREATE_ENTRY_COMPLETE); |
| 1065 cache_pending_ = true; | 1090 cache_pending_ = true; |
| 1066 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_CREATE_ENTRY); | 1091 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_CREATE_ENTRY); |
| 1067 return cache_->CreateEntry(cache_key_, &new_entry_, this); | 1092 return cache_->CreateEntry(cache_key_, &new_entry_, this); |
| 1068 } | 1093 } |
| 1069 | 1094 |
| 1070 int HttpCache::Transaction::DoCreateEntryComplete(int result) { | 1095 int HttpCache::Transaction::DoCreateEntryComplete(int result) { |
| 1071 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntryComplete"); | 1096 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntryComplete"); |
| 1072 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is | 1097 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is |
| 1073 // OK, otherwise the cache will end up with an active entry without any | 1098 // OK, otherwise the cache will end up with an active entry without any |
| 1074 // transaction attached. | 1099 // transaction attached. |
| 1075 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_CREATE_ENTRY, | 1100 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_CREATE_ENTRY, |
| 1076 result); | 1101 result); |
| 1077 cache_pending_ = false; | 1102 cache_pending_ = false; |
| 1078 switch (result) { | 1103 switch (result) { |
| 1079 case OK: | 1104 case OK: |
| 1080 TransitionToState(STATE_ADD_TO_ENTRY); | 1105 TransitionToState(STATE_ADD_TO_ENTRY); |
| 1081 break; | 1106 break; |
| 1082 | 1107 |
| 1083 case ERR_CACHE_RACE: | 1108 case ERR_CACHE_RACE: |
| 1084 TransitionToState(STATE_INIT_ENTRY); | 1109 TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); |
| 1085 break; | 1110 break; |
| 1086 | 1111 |
| 1087 default: | 1112 default: |
| 1088 // We have a race here: Maybe we failed to open the entry and decided to | 1113 // We have a race here: Maybe we failed to open the entry and decided to |
| 1089 // create one, but by the time we called create, another transaction | 1114 // create one, but by the time we called create, another transaction |
| 1090 // already created the entry. If we want to eliminate this issue, we | 1115 // already created the entry. If we want to eliminate this issue, we |
| 1091 // need an atomic OpenOrCreate() method exposed by the disk cache. | 1116 // need an atomic OpenOrCreate() method exposed by the disk cache. |
| 1092 DLOG(WARNING) << "Unable to create cache entry"; | 1117 DLOG(WARNING) << "Unable to create cache entry"; |
| 1093 mode_ = NONE; | 1118 mode_ = NONE; |
| 1094 if (partial_) | 1119 if (partial_) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 DCHECK(new_entry_); | 1180 DCHECK(new_entry_); |
| 1156 cache_pending_ = false; | 1181 cache_pending_ = false; |
| 1157 | 1182 |
| 1158 if (result == OK) | 1183 if (result == OK) |
| 1159 entry_ = new_entry_; | 1184 entry_ = new_entry_; |
| 1160 | 1185 |
| 1161 // If there is a failure, the cache should have taken care of new_entry_. | 1186 // If there is a failure, the cache should have taken care of new_entry_. |
| 1162 new_entry_ = NULL; | 1187 new_entry_ = NULL; |
| 1163 | 1188 |
| 1164 if (result == ERR_CACHE_RACE) { | 1189 if (result == ERR_CACHE_RACE) { |
| 1165 TransitionToState(STATE_INIT_ENTRY); | 1190 TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); |
| 1166 return OK; | 1191 return OK; |
| 1167 } | 1192 } |
| 1168 | 1193 |
| 1169 if (result == ERR_CACHE_LOCK_TIMEOUT) { | 1194 if (result == ERR_CACHE_LOCK_TIMEOUT) { |
| 1170 if (mode_ == READ) { | 1195 if (mode_ == READ) { |
| 1171 TransitionToState(STATE_NONE); | 1196 TransitionToState(STATE_FINISH_HEADERS); |
| 1172 return ERR_CACHE_MISS; | 1197 return ERR_CACHE_MISS; |
| 1173 } | 1198 } |
| 1174 | 1199 |
| 1175 // The cache is busy, bypass it for this transaction. | 1200 // The cache is busy, bypass it for this transaction. |
| 1176 mode_ = NONE; | 1201 mode_ = NONE; |
| 1177 TransitionToState(STATE_SEND_REQUEST); | 1202 TransitionToState(STATE_SEND_REQUEST); |
| 1178 if (partial_) { | 1203 if (partial_) { |
| 1179 partial_->RestoreHeaders(&custom_request_->extra_headers); | 1204 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 1180 partial_.reset(); | 1205 partial_.reset(); |
| 1181 } | 1206 } |
| 1182 return OK; | 1207 return OK; |
| 1183 } | 1208 } |
| 1184 | 1209 |
| 1185 open_entry_last_used_ = entry_->disk_entry->GetLastUsed(); | 1210 // TODO(crbug.com/713354) Access timestamp for histograms only if entry is |
| 1211 // already written, to avoid data race since cache thread can also access |
| 1212 // this. |
| 1213 if (!cache_->IsWritingInProgress(entry_)) |
| 1214 open_entry_last_used_ = entry_->disk_entry->GetLastUsed(); |
| 1186 | 1215 |
| 1187 // TODO(jkarlin): We should either handle the case or DCHECK. | 1216 // TODO(jkarlin): We should either handle the case or DCHECK. |
| 1188 if (result != OK) { | 1217 if (result != OK) { |
| 1189 NOTREACHED(); | 1218 NOTREACHED(); |
| 1190 TransitionToState(STATE_NONE); | 1219 TransitionToState(STATE_FINISH_HEADERS); |
| 1191 return result; | 1220 return result; |
| 1192 } | 1221 } |
| 1193 | 1222 |
| 1194 if (mode_ == WRITE) { | 1223 if (mode_ == WRITE) { |
| 1195 if (partial_) | 1224 if (partial_) |
| 1196 partial_->RestoreHeaders(&custom_request_->extra_headers); | 1225 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 1197 TransitionToState(STATE_SEND_REQUEST); | 1226 TransitionToState(STATE_SEND_REQUEST); |
| 1198 } else { | 1227 } else { |
| 1199 // We have to read the headers from the cached entry. | 1228 // We have to read the headers from the cached entry. |
| 1200 DCHECK(mode_ & READ_META); | 1229 DCHECK(mode_ & READ_META); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1219 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { | 1248 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { |
| 1220 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadResponseComplete"); | 1249 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadResponseComplete"); |
| 1221 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, | 1250 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, |
| 1222 result); | 1251 result); |
| 1223 if (result != io_buf_len_ || | 1252 if (result != io_buf_len_ || |
| 1224 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, &response_, | 1253 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, &response_, |
| 1225 &truncated_)) { | 1254 &truncated_)) { |
| 1226 return OnCacheReadError(result, true); | 1255 return OnCacheReadError(result, true); |
| 1227 } | 1256 } |
| 1228 | 1257 |
| 1229 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 1258 // TODO(crbug.com/713354) Only get data size if there is no other transaction |
| 1230 int64_t full_response_length = response_.headers->GetContentLength(); | 1259 // currently writing the response body due to the data race mentioned in the |
| 1260 // associated bug. |
| 1261 if (!cache_->IsWritingInProgress(entry_)) { |
| 1262 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1263 int64_t full_response_length = response_.headers->GetContentLength(); |
| 1231 | 1264 |
| 1232 // Some resources may have slipped in as truncated when they're not. | 1265 // Some resources may have slipped in as truncated when they're not. |
| 1233 if (full_response_length == current_size) | 1266 if (full_response_length == current_size) |
| 1234 truncated_ = false; | 1267 truncated_ = false; |
| 1235 | 1268 |
| 1236 // The state machine's handling of StopCaching unfortunately doesn't deal well | 1269 // The state machine's handling of StopCaching unfortunately doesn't deal |
| 1237 // with resources that are larger than 2GB when there is a truncated or sparse | 1270 // well with resources that are larger than 2GB when there is a truncated or |
| 1238 // cache entry. While the state machine is reworked to resolve this, the | 1271 // sparse cache entry. While the state machine is reworked to resolve this, |
| 1239 // following logic is put in place to defer such requests to the network. The | 1272 // the following logic is put in place to defer such requests to the |
| 1240 // cache should not be storing multi gigabyte resources. See | 1273 // network. The cache should not be storing multi gigabyte resources. See |
| 1241 // http://crbug.com/89567. | 1274 // http://crbug.com/89567. |
| 1242 if ((truncated_ || response_.headers->response_code() == 206) && | 1275 if ((truncated_ || response_.headers->response_code() == 206) && |
| 1243 !range_requested_ && | 1276 !range_requested_ && |
| 1244 full_response_length > std::numeric_limits<int32_t>::max()) { | 1277 full_response_length > std::numeric_limits<int32_t>::max()) { |
| 1245 // Does not release the cache entry. If another transaction wants to use | 1278 DCHECK(!partial_); |
| 1246 // this cache entry while this transaction is active, the second transaction | 1279 |
| 1247 // will fall back to the network after the timeout. | 1280 // Doom the entry so that no other transaction gets added to this entry |
| 1248 DCHECK(!partial_); | 1281 // and avoid a race of not being able to check this condition because |
| 1249 mode_ = NONE; | 1282 // writing is in progress. |
| 1250 TransitionToState(STATE_SEND_REQUEST); | 1283 cache_->DoneWritingToEntry(entry_, false, this); |
| 1251 return OK; | 1284 entry_ = nullptr; |
| 1285 mode_ = NONE; |
| 1286 TransitionToState(STATE_SEND_REQUEST); |
| 1287 return OK; |
| 1288 } |
| 1252 } | 1289 } |
| 1253 | 1290 |
| 1254 if (response_.unused_since_prefetch != | 1291 if (response_.unused_since_prefetch != |
| 1255 !!(request_->load_flags & LOAD_PREFETCH)) { | 1292 !!(request_->load_flags & LOAD_PREFETCH)) { |
| 1256 // Either this is the first use of an entry since it was prefetched XOR | 1293 // Either this is the first use of an entry since it was prefetched XOR |
| 1257 // this is a prefetch. The value of response.unused_since_prefetch is | 1294 // this is a prefetch. The value of response.unused_since_prefetch is |
| 1258 // valid for this transaction but the bit needs to be flipped in storage. | 1295 // valid for this transaction but the bit needs to be flipped in storage. |
| 1259 TransitionToState(STATE_TOGGLE_UNUSED_SINCE_PREFETCH); | 1296 TransitionToState(STATE_TOGGLE_UNUSED_SINCE_PREFETCH); |
| 1260 return OK; | 1297 return OK; |
| 1261 } | 1298 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 } | 1360 } |
| 1324 | 1361 |
| 1325 int HttpCache::Transaction::DoCacheQueryData() { | 1362 int HttpCache::Transaction::DoCacheQueryData() { |
| 1326 TransitionToState(STATE_CACHE_QUERY_DATA_COMPLETE); | 1363 TransitionToState(STATE_CACHE_QUERY_DATA_COMPLETE); |
| 1327 return entry_->disk_entry->ReadyForSparseIO(io_callback_); | 1364 return entry_->disk_entry->ReadyForSparseIO(io_callback_); |
| 1328 } | 1365 } |
| 1329 | 1366 |
| 1330 int HttpCache::Transaction::DoCacheQueryDataComplete(int result) { | 1367 int HttpCache::Transaction::DoCacheQueryDataComplete(int result) { |
| 1331 DCHECK_EQ(OK, result); | 1368 DCHECK_EQ(OK, result); |
| 1332 if (!cache_.get()) { | 1369 if (!cache_.get()) { |
| 1333 TransitionToState(STATE_NONE); | 1370 TransitionToState(STATE_FINISH_HEADERS); |
| 1334 return ERR_UNEXPECTED; | 1371 return ERR_UNEXPECTED; |
| 1335 } | 1372 } |
| 1336 | 1373 |
| 1337 return ValidateEntryHeadersAndContinue(); | 1374 return ValidateEntryHeadersAndContinue(); |
| 1338 } | 1375 } |
| 1339 | 1376 |
| 1340 // We may end up here multiple times for a given request. | 1377 // We may end up here multiple times for a given request. |
| 1341 int HttpCache::Transaction::DoStartPartialCacheValidation() { | 1378 int HttpCache::Transaction::DoStartPartialCacheValidation() { |
| 1342 if (mode_ == NONE) { | 1379 if (mode_ == NONE) { |
| 1343 TransitionToState(STATE_NONE); | 1380 TransitionToState(STATE_FINISH_HEADERS); |
| 1344 return OK; | 1381 return OK; |
| 1345 } | 1382 } |
| 1346 | 1383 |
| 1347 TransitionToState(STATE_COMPLETE_PARTIAL_CACHE_VALIDATION); | 1384 TransitionToState(STATE_COMPLETE_PARTIAL_CACHE_VALIDATION); |
| 1348 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); | 1385 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); |
| 1349 } | 1386 } |
| 1350 | 1387 |
| 1351 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { | 1388 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { |
| 1352 if (!result) { | 1389 if (!result) { |
| 1353 // This is the end of the request. | 1390 // This is the end of the request. |
| 1354 if (mode_ & WRITE) { | 1391 if (mode_ & WRITE) { |
| 1355 DoneWritingToEntry(true); | 1392 DoneWritingToEntry(true); |
| 1356 } else { | 1393 } else { |
| 1357 cache_->DoneReadingFromEntry(entry_, this); | 1394 cache_->DoneWithEntry(entry_, this, false /* process_cancel */, |
| 1395 partial_ != nullptr); |
| 1358 entry_ = NULL; | 1396 entry_ = NULL; |
| 1359 } | 1397 } |
| 1360 TransitionToState(STATE_NONE); | 1398 TransitionToState(STATE_FINISH_HEADERS); |
| 1361 return result; | 1399 return result; |
| 1362 } | 1400 } |
| 1363 | 1401 |
| 1364 if (result < 0) { | 1402 if (result < 0) { |
| 1365 TransitionToState(STATE_NONE); | 1403 TransitionToState(STATE_FINISH_HEADERS); |
| 1366 return result; | 1404 return result; |
| 1367 } | 1405 } |
| 1368 | 1406 |
| 1369 partial_->PrepareCacheValidation(entry_->disk_entry, | 1407 partial_->PrepareCacheValidation(entry_->disk_entry, |
| 1370 &custom_request_->extra_headers); | 1408 &custom_request_->extra_headers); |
| 1371 | 1409 |
| 1372 if (reading_ && partial_->IsCurrentRangeCached()) { | 1410 if (reading_ && partial_->IsCurrentRangeCached()) { |
| 1373 TransitionToState(STATE_CACHE_READ_DATA); | 1411 TransitionToState(STATE_CACHE_READ_DATA); |
| 1374 return OK; | 1412 return OK; |
| 1375 } | 1413 } |
| 1376 | 1414 |
| 1377 return BeginCacheValidation(); | 1415 return BeginCacheValidation(); |
| 1378 } | 1416 } |
| 1379 | 1417 |
| 1380 int HttpCache::Transaction::DoSendRequest() { | 1418 int HttpCache::Transaction::DoSendRequest() { |
| 1381 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequest"); | 1419 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequest"); |
| 1382 DCHECK(mode_ & WRITE || mode_ == NONE); | 1420 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 1383 DCHECK(!network_trans_.get()); | 1421 DCHECK(!network_trans_.get()); |
| 1384 | 1422 |
| 1385 send_request_since_ = TimeTicks::Now(); | 1423 send_request_since_ = TimeTicks::Now(); |
| 1386 | 1424 |
| 1387 // Create a network transaction. | 1425 // Create a network transaction. |
| 1388 int rv = | 1426 int rv = |
| 1389 cache_->network_layer_->CreateTransaction(priority_, &network_trans_); | 1427 cache_->network_layer_->CreateTransaction(priority_, &network_trans_); |
| 1390 if (rv != OK) { | 1428 if (rv != OK) { |
| 1391 TransitionToState(STATE_NONE); | 1429 TransitionToState(STATE_FINISH_HEADERS); |
| 1392 return rv; | 1430 return rv; |
| 1393 } | 1431 } |
| 1394 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_); | 1432 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_); |
| 1395 network_trans_->SetBeforeHeadersSentCallback(before_headers_sent_callback_); | 1433 network_trans_->SetBeforeHeadersSentCallback(before_headers_sent_callback_); |
| 1396 | 1434 |
| 1397 // Old load timing information, if any, is now obsolete. | 1435 // Old load timing information, if any, is now obsolete. |
| 1398 old_network_trans_load_timing_.reset(); | 1436 old_network_trans_load_timing_.reset(); |
| 1399 old_remote_endpoint_ = IPEndPoint(); | 1437 old_remote_endpoint_ = IPEndPoint(); |
| 1400 | 1438 |
| 1401 if (websocket_handshake_stream_base_create_helper_) | 1439 if (websocket_handshake_stream_base_create_helper_) |
| 1402 network_trans_->SetWebSocketHandshakeStreamCreateHelper( | 1440 network_trans_->SetWebSocketHandshakeStreamCreateHelper( |
| 1403 websocket_handshake_stream_base_create_helper_); | 1441 websocket_handshake_stream_base_create_helper_); |
| 1404 | 1442 |
| 1405 TransitionToState(STATE_SEND_REQUEST_COMPLETE); | 1443 TransitionToState(STATE_SEND_REQUEST_COMPLETE); |
| 1406 rv = network_trans_->Start(request_, io_callback_, net_log_); | 1444 rv = network_trans_->Start(request_, io_callback_, net_log_); |
| 1407 return rv; | 1445 return rv; |
| 1408 } | 1446 } |
| 1409 | 1447 |
| 1410 int HttpCache::Transaction::DoSendRequestComplete(int result) { | 1448 int HttpCache::Transaction::DoSendRequestComplete(int result) { |
| 1411 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequestComplete"); | 1449 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequestComplete"); |
| 1412 if (!cache_.get()) { | 1450 if (!cache_.get()) { |
| 1413 TransitionToState(STATE_NONE); | 1451 TransitionToState(STATE_FINISH_HEADERS); |
| 1414 return ERR_UNEXPECTED; | 1452 return ERR_UNEXPECTED; |
| 1415 } | 1453 } |
| 1416 | 1454 |
| 1417 // If we tried to conditionalize the request and failed, we know | 1455 // If we tried to conditionalize the request and failed, we know |
| 1418 // we won't be reading from the cache after this point. | 1456 // we won't be reading from the cache after this point. |
| 1419 if (couldnt_conditionalize_request_) | 1457 if (couldnt_conditionalize_request_) |
| 1420 mode_ = WRITE; | 1458 mode_ = WRITE; |
| 1421 | 1459 |
| 1422 if (result == OK) { | 1460 if (result == OK) { |
| 1423 TransitionToState(STATE_SUCCESSFUL_SEND_REQUEST); | 1461 TransitionToState(STATE_SUCCESSFUL_SEND_REQUEST); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1434 // so GetResponseInfo() should never return NULL here. | 1472 // so GetResponseInfo() should never return NULL here. |
| 1435 DCHECK(response); | 1473 DCHECK(response); |
| 1436 response_.ssl_info = response->ssl_info; | 1474 response_.ssl_info = response->ssl_info; |
| 1437 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 1475 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 1438 DCHECK(response); | 1476 DCHECK(response); |
| 1439 response_.cert_request_info = response->cert_request_info; | 1477 response_.cert_request_info = response->cert_request_info; |
| 1440 } else if (response_.was_cached) { | 1478 } else if (response_.was_cached) { |
| 1441 DoneWritingToEntry(true); | 1479 DoneWritingToEntry(true); |
| 1442 } | 1480 } |
| 1443 | 1481 |
| 1444 TransitionToState(STATE_NONE); | 1482 TransitionToState(STATE_FINISH_HEADERS); |
| 1445 return result; | 1483 return result; |
| 1446 } | 1484 } |
| 1447 | 1485 |
| 1448 // We received the response headers and there is no error. | 1486 // We received the response headers and there is no error. |
| 1449 int HttpCache::Transaction::DoSuccessfulSendRequest() { | 1487 int HttpCache::Transaction::DoSuccessfulSendRequest() { |
| 1450 TRACE_EVENT0("io", "HttpCacheTransaction::DoSuccessfulSendRequest"); | 1488 TRACE_EVENT0("io", "HttpCacheTransaction::DoSuccessfulSendRequest"); |
| 1451 DCHECK(!new_response_); | 1489 DCHECK(!new_response_); |
| 1452 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); | 1490 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); |
| 1453 | 1491 |
| 1454 if (new_response->headers->response_code() == 401 || | 1492 if (new_response->headers->response_code() == 401 || |
| 1455 new_response->headers->response_code() == 407) { | 1493 new_response->headers->response_code() == 407) { |
| 1456 SetAuthResponse(*new_response); | 1494 SetAuthResponse(*new_response); |
| 1457 if (!reading_) { | 1495 if (!reading_) { |
| 1458 TransitionToState(STATE_NONE); | 1496 TransitionToState(STATE_FINISH_HEADERS); |
| 1459 return OK; | 1497 return OK; |
| 1460 } | 1498 } |
| 1461 | 1499 |
| 1462 // We initiated a second request the caller doesn't know about. We should be | 1500 // We initiated a second request the caller doesn't know about. We should be |
| 1463 // able to authenticate this request because we should have authenticated | 1501 // able to authenticate this request because we should have authenticated |
| 1464 // this URL moments ago. | 1502 // this URL moments ago. |
| 1465 if (IsReadyToRestartForAuth()) { | 1503 if (IsReadyToRestartForAuth()) { |
| 1466 DCHECK(!response_.auth_challenge.get()); | 1504 DCHECK(!response_.auth_challenge.get()); |
| 1467 TransitionToState(STATE_SEND_REQUEST_COMPLETE); | 1505 TransitionToState(STATE_SEND_REQUEST_COMPLETE); |
| 1468 // In theory we should check to see if there are new cookies, but there | 1506 // In theory we should check to see if there are new cookies, but there |
| 1469 // is no way to do that from here. | 1507 // is no way to do that from here. |
| 1470 return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_); | 1508 return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_); |
| 1471 } | 1509 } |
| 1472 | 1510 |
| 1473 // We have to perform cleanup at this point so that at least the next | 1511 // We have to perform cleanup at this point so that at least the next |
| 1474 // request can succeed. We do not retry at this point, because data | 1512 // request can succeed. We do not retry at this point, because data |
| 1475 // has been read and we have no way to gather credentials. We would | 1513 // has been read and we have no way to gather credentials. We would |
| 1476 // fail again, and potentially loop. This can happen if the credentials | 1514 // fail again, and potentially loop. This can happen if the credentials |
| 1477 // expire while chrome is suspended. | 1515 // expire while chrome is suspended. |
| 1478 if (entry_) | 1516 if (entry_) |
| 1479 DoomPartialEntry(false); | 1517 DoomPartialEntry(false); |
| 1480 mode_ = NONE; | 1518 mode_ = NONE; |
| 1481 partial_.reset(); | 1519 partial_.reset(); |
| 1482 ResetNetworkTransaction(); | 1520 ResetNetworkTransaction(); |
| 1483 TransitionToState(STATE_NONE); | 1521 TransitionToState(STATE_FINISH_HEADERS); |
| 1484 return ERR_CACHE_AUTH_FAILURE_AFTER_READ; | 1522 return ERR_CACHE_AUTH_FAILURE_AFTER_READ; |
| 1485 } | 1523 } |
| 1486 | 1524 |
| 1487 new_response_ = new_response; | 1525 new_response_ = new_response; |
| 1488 if (!ValidatePartialResponse() && !auth_response_.headers.get()) { | 1526 if (!ValidatePartialResponse() && !auth_response_.headers.get()) { |
| 1489 // Something went wrong with this request and we have to restart it. | 1527 // Something went wrong with this request and we have to restart it. |
| 1490 // If we have an authentication response, we are exposed to weird things | 1528 // If we have an authentication response, we are exposed to weird things |
| 1491 // hapenning if the user cancels the authentication before we receive | 1529 // hapenning if the user cancels the authentication before we receive |
| 1492 // the new response. | 1530 // the new response. |
| 1493 net_log_.AddEvent(NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); | 1531 net_log_.AddEvent(NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1505 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); | 1543 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); |
| 1506 DoneWritingToEntry(false); | 1544 DoneWritingToEntry(false); |
| 1507 } | 1545 } |
| 1508 | 1546 |
| 1509 if (mode_ == WRITE && | 1547 if (mode_ == WRITE && |
| 1510 cache_entry_status_ != CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { | 1548 cache_entry_status_ != CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { |
| 1511 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_NOT_IN_CACHE); | 1549 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_NOT_IN_CACHE); |
| 1512 } | 1550 } |
| 1513 | 1551 |
| 1514 // Invalidate any cached GET with a successful PUT or DELETE. | 1552 // Invalidate any cached GET with a successful PUT or DELETE. |
| 1515 if (mode_ == WRITE && | 1553 if (mode_ == WRITE && (method_ == "PUT" || method_ == "DELETE")) { |
| 1516 (request_->method == "PUT" || request_->method == "DELETE")) { | |
| 1517 if (NonErrorResponse(new_response->headers->response_code())) { | 1554 if (NonErrorResponse(new_response->headers->response_code())) { |
| 1518 int ret = cache_->DoomEntry(cache_key_, NULL); | 1555 int ret = cache_->DoomEntry(cache_key_, NULL); |
| 1519 DCHECK_EQ(OK, ret); | 1556 DCHECK_EQ(OK, ret); |
| 1520 } | 1557 } |
| 1521 cache_->DoneWritingToEntry(entry_, true); | 1558 cache_->DoneWritingToEntry(entry_, true, this); |
| 1522 entry_ = NULL; | 1559 entry_ = NULL; |
| 1523 mode_ = NONE; | 1560 mode_ = NONE; |
| 1524 } | 1561 } |
| 1525 | 1562 |
| 1526 // Invalidate any cached GET with a successful POST. | 1563 // Invalidate any cached GET with a successful POST. |
| 1527 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && | 1564 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && method_ == "POST" && |
| 1528 request_->method == "POST" && | |
| 1529 NonErrorResponse(new_response->headers->response_code())) { | 1565 NonErrorResponse(new_response->headers->response_code())) { |
| 1530 cache_->DoomMainEntryForUrl(request_->url); | 1566 cache_->DoomMainEntryForUrl(request_->url); |
| 1531 } | 1567 } |
| 1532 | 1568 |
| 1533 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); | 1569 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); |
| 1534 | 1570 |
| 1535 if (new_response_->headers->response_code() == 416 && | 1571 if (new_response_->headers->response_code() == 416 && |
| 1536 (request_->method == "GET" || request_->method == "POST")) { | 1572 (method_ == "GET" || method_ == "POST")) { |
| 1537 // If there is an active entry it may be destroyed with this transaction. | 1573 // If there is an active entry it may be destroyed with this transaction. |
| 1538 SetResponse(*new_response_); | 1574 SetResponse(*new_response_); |
| 1539 TransitionToState(STATE_NONE); | 1575 TransitionToState(STATE_FINISH_HEADERS); |
| 1540 return OK; | 1576 return OK; |
| 1541 } | 1577 } |
| 1542 | 1578 |
| 1543 // Are we expecting a response to a conditional query? | 1579 // Are we expecting a response to a conditional query? |
| 1544 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 1580 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
| 1545 if (new_response->headers->response_code() == 304 || handling_206_) { | 1581 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 1546 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); | 1582 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); |
| 1547 TransitionToState(STATE_UPDATE_CACHED_RESPONSE); | 1583 TransitionToState(STATE_UPDATE_CACHED_RESPONSE); |
| 1548 return OK; | 1584 return OK; |
| 1549 } | 1585 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 DCHECK(!handling_206_); | 1653 DCHECK(!handling_206_); |
| 1618 // We got a "not modified" response and already updated the corresponding | 1654 // We got a "not modified" response and already updated the corresponding |
| 1619 // cache entry above. | 1655 // cache entry above. |
| 1620 // | 1656 // |
| 1621 // By closing the cached entry now, we make sure that the 304 rather than | 1657 // By closing the cached entry now, we make sure that the 304 rather than |
| 1622 // the cached 200 response, is what will be returned to the user. | 1658 // the cached 200 response, is what will be returned to the user. |
| 1623 DoneWritingToEntry(true); | 1659 DoneWritingToEntry(true); |
| 1624 } else if (entry_ && !handling_206_) { | 1660 } else if (entry_ && !handling_206_) { |
| 1625 DCHECK_EQ(READ_WRITE, mode_); | 1661 DCHECK_EQ(READ_WRITE, mode_); |
| 1626 if (!partial_ || partial_->IsLastRange()) { | 1662 if (!partial_ || partial_->IsLastRange()) { |
| 1627 cache_->ConvertWriterToReader(entry_); | |
| 1628 mode_ = READ; | 1663 mode_ = READ; |
| 1629 } | 1664 } |
| 1630 // We no longer need the network transaction, so destroy it. | 1665 // We no longer need the network transaction, so destroy it. |
| 1631 ResetNetworkTransaction(); | 1666 ResetNetworkTransaction(); |
| 1632 } else if (entry_ && handling_206_ && truncated_ && | 1667 } else if (entry_ && handling_206_ && truncated_ && |
| 1633 partial_->initial_validation()) { | 1668 partial_->initial_validation()) { |
| 1634 // We just finished the validation of a truncated entry, and the server | 1669 // We just finished the validation of a truncated entry, and the server |
| 1635 // is willing to resume the operation. Now we go back and start serving | 1670 // is willing to resume the operation. Now we go back and start serving |
| 1636 // the first part to the user. | 1671 // the first part to the user. |
| 1637 ResetNetworkTransaction(); | 1672 ResetNetworkTransaction(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1650 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); | 1685 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); |
| 1651 return OK; | 1686 return OK; |
| 1652 } | 1687 } |
| 1653 | 1688 |
| 1654 // We change the value of Content-Length for partial content. | 1689 // We change the value of Content-Length for partial content. |
| 1655 if (handling_206_ && partial_) | 1690 if (handling_206_ && partial_) |
| 1656 partial_->FixContentLength(new_response_->headers.get()); | 1691 partial_->FixContentLength(new_response_->headers.get()); |
| 1657 | 1692 |
| 1658 SetResponse(*new_response_); | 1693 SetResponse(*new_response_); |
| 1659 | 1694 |
| 1660 if (request_->method == "HEAD") { | 1695 if (method_ == "HEAD") { |
| 1661 // This response is replacing the cached one. | 1696 // This response is replacing the cached one. |
| 1662 DoneWritingToEntry(false); | 1697 DoneWritingToEntry(false); |
| 1663 mode_ = NONE; | 1698 mode_ = NONE; |
| 1664 new_response_ = NULL; | 1699 new_response_ = NULL; |
| 1665 TransitionToState(STATE_NONE); | 1700 TransitionToState(STATE_FINISH_HEADERS); |
| 1666 return OK; | 1701 return OK; |
| 1667 } | 1702 } |
| 1668 | 1703 |
| 1669 if (handling_206_ && !CanResume(false)) { | 1704 if (handling_206_ && !CanResume(false)) { |
| 1670 // There is no point in storing this resource because it will never be used. | 1705 // There is no point in storing this resource because it will never be used. |
| 1671 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. | 1706 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. |
| 1672 DoneWritingToEntry(false); | 1707 DoneWritingToEntry(false); |
| 1673 if (partial_) | 1708 if (partial_) |
| 1674 partial_->FixResponseHeaders(response_.headers.get(), true); | 1709 partial_->FixResponseHeaders(response_.headers.get(), true); |
| 1675 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); | 1710 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); |
| 1676 return OK; | 1711 return OK; |
| 1677 } | 1712 } |
| 1678 | 1713 |
| 1679 TransitionToState(STATE_CACHE_WRITE_RESPONSE); | 1714 TransitionToState(STATE_CACHE_WRITE_RESPONSE); |
| 1680 return OK; | 1715 return OK; |
| 1681 } | 1716 } |
| 1682 | 1717 |
| 1683 int HttpCache::Transaction::DoCacheWriteResponse() { | 1718 int HttpCache::Transaction::DoCacheWriteResponse() { |
| 1684 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); | 1719 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); |
| 1685 TransitionToState(STATE_CACHE_WRITE_RESPONSE_COMPLETE); | 1720 TransitionToState(STATE_CACHE_WRITE_RESPONSE_COMPLETE); |
| 1721 |
| 1722 // Invalidate any current entry with a successful response if this transaction |
| 1723 // cannot write to this entry. This transaction then continues to read from |
| 1724 // the network without writing to the backend. |
| 1725 bool is_match = response_.headers->response_code() == 304; |
| 1726 if (entry_ && response_.headers && |
| 1727 !cache_->CanTransactionWriteResponseHeaders( |
| 1728 entry_, this, partial_ != nullptr, is_match)) { |
| 1729 cache_->DoneWritingToEntry(entry_, false, this); |
| 1730 entry_ = nullptr; |
| 1731 mode_ = NONE; |
| 1732 return OK; |
| 1733 } |
| 1734 |
| 1686 return WriteResponseInfoToEntry(truncated_); | 1735 return WriteResponseInfoToEntry(truncated_); |
| 1687 } | 1736 } |
| 1688 | 1737 |
| 1689 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { | 1738 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { |
| 1690 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); | 1739 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); |
| 1691 TransitionToState(STATE_TRUNCATE_CACHED_DATA); | 1740 TransitionToState(STATE_TRUNCATE_CACHED_DATA); |
| 1692 return OnWriteResponseInfoToEntryComplete(result); | 1741 return OnWriteResponseInfoToEntryComplete(result); |
| 1693 } | 1742 } |
| 1694 | 1743 |
| 1695 int HttpCache::Transaction::DoTruncateCachedData() { | 1744 int HttpCache::Transaction::DoTruncateCachedData() { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1737 } | 1786 } |
| 1738 | 1787 |
| 1739 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); | 1788 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); |
| 1740 return OK; | 1789 return OK; |
| 1741 } | 1790 } |
| 1742 | 1791 |
| 1743 int HttpCache::Transaction::DoPartialHeadersReceived() { | 1792 int HttpCache::Transaction::DoPartialHeadersReceived() { |
| 1744 new_response_ = NULL; | 1793 new_response_ = NULL; |
| 1745 | 1794 |
| 1746 if (!partial_) { | 1795 if (!partial_) { |
| 1747 if (entry_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1796 if (entry_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) { |
| 1748 TransitionToState(STATE_CACHE_READ_METADATA); | 1797 TransitionToState(STATE_CACHE_READ_METADATA); |
| 1749 else | 1798 } else { |
| 1750 TransitionToState(STATE_NONE); | 1799 TransitionToState(STATE_FINISH_HEADERS); |
| 1800 } |
| 1751 return OK; | 1801 return OK; |
| 1752 } | 1802 } |
| 1753 | 1803 |
| 1754 if (reading_) { | 1804 if (reading_) { |
| 1755 if (network_trans_.get()) { | 1805 if (network_trans_.get()) { |
| 1756 TransitionToState(STATE_NETWORK_READ); | 1806 TransitionToState(STATE_NETWORK_READ); |
| 1757 } else { | 1807 } else { |
| 1758 TransitionToState(STATE_CACHE_READ_DATA); | 1808 TransitionToState(STATE_CACHE_READ_DATA); |
| 1759 } | 1809 } |
| 1760 } else if (mode_ != NONE) { | 1810 } else if (mode_ != NONE) { |
| 1761 // We are about to return the headers for a byte-range request to the user, | 1811 // We are about to return the headers for a byte-range request to the user, |
| 1762 // so let's fix them. | 1812 // so let's fix them. |
| 1763 partial_->FixResponseHeaders(response_.headers.get(), true); | 1813 partial_->FixResponseHeaders(response_.headers.get(), true); |
| 1764 TransitionToState(STATE_NONE); | 1814 TransitionToState(STATE_FINISH_HEADERS); |
| 1765 } else { | 1815 } else { |
| 1766 TransitionToState(STATE_NONE); | 1816 TransitionToState(STATE_FINISH_HEADERS); |
| 1767 } | 1817 } |
| 1768 return OK; | 1818 return OK; |
| 1769 } | 1819 } |
| 1770 | 1820 |
| 1821 int HttpCache::Transaction::DoHeadersPhaseCannotProceed() { |
| 1822 // If its the Start state machine and it cannot proceed due to a cache |
| 1823 // failure, restart this transaction. |
| 1824 DCHECK(!reading_); |
| 1825 TransitionToState(STATE_INIT_ENTRY); |
| 1826 cache_entry_status_ = restart_info_.cache_entry_status; |
| 1827 entry_ = nullptr; |
| 1828 mode_ = restart_info_.mode; |
| 1829 if (network_trans_) |
| 1830 network_trans_.reset(); |
| 1831 |
| 1832 return OK; |
| 1833 } |
| 1834 |
| 1835 int HttpCache::Transaction::DoFinishHeaders(int result) { |
| 1836 if (!entry_ || result != OK) { |
| 1837 TransitionToState(STATE_NONE); |
| 1838 return result; |
| 1839 } |
| 1840 |
| 1841 TransitionToState(STATE_FINISH_HEADERS_COMPLETE); |
| 1842 |
| 1843 // If it was an auth failure or 416, this transaction should continue to be |
| 1844 // headers_transaction till consumer takes an action, so no need to do |
| 1845 // anything now. |
| 1846 if (auth_response_.headers.get() || |
| 1847 (new_response_ && new_response_->headers && |
| 1848 new_response_->headers->response_code() == 416)) |
| 1849 return OK; |
| 1850 |
| 1851 // If the transaction needs to wait because another transaction is still |
| 1852 // writing the response body, it will return ERR_IO_PENDING now and the |
| 1853 // io_callback_ will be invoked when the wait is done. |
| 1854 return cache_->DoneWithResponseHeaders(entry_, this, partial_ != nullptr); |
| 1855 } |
| 1856 |
| 1857 int HttpCache::Transaction::DoFinishHeadersComplete(int rv) { |
| 1858 if (rv == ERR_CACHE_RACE) { |
| 1859 TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); |
| 1860 return OK; |
| 1861 } |
| 1862 |
| 1863 TransitionToState(STATE_NONE); |
| 1864 return rv; |
| 1865 } |
| 1866 |
| 1771 int HttpCache::Transaction::DoCacheReadMetadata() { | 1867 int HttpCache::Transaction::DoCacheReadMetadata() { |
| 1772 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata"); | 1868 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata"); |
| 1773 DCHECK(entry_); | 1869 DCHECK(entry_); |
| 1774 DCHECK(!response_.metadata.get()); | 1870 DCHECK(!response_.metadata.get()); |
| 1775 TransitionToState(STATE_CACHE_READ_METADATA_COMPLETE); | 1871 TransitionToState(STATE_CACHE_READ_METADATA_COMPLETE); |
| 1776 | 1872 |
| 1777 response_.metadata = | 1873 response_.metadata = |
| 1778 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); | 1874 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); |
| 1779 | 1875 |
| 1780 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO); | 1876 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO); |
| 1781 return entry_->disk_entry->ReadData(kMetadataIndex, 0, | 1877 return entry_->disk_entry->ReadData(kMetadataIndex, 0, |
| 1782 response_.metadata.get(), | 1878 response_.metadata.get(), |
| 1783 response_.metadata->size(), | 1879 response_.metadata->size(), |
| 1784 io_callback_); | 1880 io_callback_); |
| 1785 } | 1881 } |
| 1786 | 1882 |
| 1787 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { | 1883 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { |
| 1788 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadataComplete"); | 1884 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadataComplete"); |
| 1789 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, | 1885 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, |
| 1790 result); | 1886 result); |
| 1791 if (result != response_.metadata->size()) | 1887 if (result != response_.metadata->size()) |
| 1792 return OnCacheReadError(result, false); | 1888 return OnCacheReadError(result, false); |
| 1793 TransitionToState(STATE_NONE); | 1889 |
| 1890 TransitionToState(STATE_FINISH_HEADERS); |
| 1794 return OK; | 1891 return OK; |
| 1795 } | 1892 } |
| 1796 | 1893 |
| 1797 int HttpCache::Transaction::DoNetworkRead() { | 1894 int HttpCache::Transaction::DoNetworkRead() { |
| 1798 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); | 1895 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); |
| 1799 TransitionToState(STATE_NETWORK_READ_COMPLETE); | 1896 TransitionToState(STATE_NETWORK_READ_COMPLETE); |
| 1800 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); | 1897 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); |
| 1801 } | 1898 } |
| 1802 | 1899 |
| 1803 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 1900 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1816 return result; | 1913 return result; |
| 1817 } | 1914 } |
| 1818 | 1915 |
| 1819 TransitionToState(STATE_CACHE_WRITE_DATA); | 1916 TransitionToState(STATE_CACHE_WRITE_DATA); |
| 1820 return result; | 1917 return result; |
| 1821 } | 1918 } |
| 1822 | 1919 |
| 1823 int HttpCache::Transaction::DoCacheReadData() { | 1920 int HttpCache::Transaction::DoCacheReadData() { |
| 1824 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); | 1921 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); |
| 1825 | 1922 |
| 1826 if (request_->method == "HEAD") { | 1923 if (method_ == "HEAD") { |
| 1827 TransitionToState(STATE_NONE); | 1924 TransitionToState(STATE_NONE); |
| 1828 return 0; | 1925 return 0; |
| 1829 } | 1926 } |
| 1830 | 1927 |
| 1831 DCHECK(entry_); | 1928 DCHECK(entry_); |
| 1832 TransitionToState(STATE_CACHE_READ_DATA_COMPLETE); | 1929 TransitionToState(STATE_CACHE_READ_DATA_COMPLETE); |
| 1833 | 1930 |
| 1834 if (net_log_.IsCapturing()) | 1931 if (net_log_.IsCapturing()) |
| 1835 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); | 1932 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); |
| 1836 if (partial_) { | 1933 if (partial_) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1954 return OnWriteResponseInfoToEntryComplete(result); | 2051 return OnWriteResponseInfoToEntryComplete(result); |
| 1955 } | 2052 } |
| 1956 | 2053 |
| 1957 //----------------------------------------------------------------------------- | 2054 //----------------------------------------------------------------------------- |
| 1958 | 2055 |
| 1959 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, | 2056 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, |
| 1960 const HttpRequestInfo* request) { | 2057 const HttpRequestInfo* request) { |
| 1961 net_log_ = net_log; | 2058 net_log_ = net_log; |
| 1962 request_ = request; | 2059 request_ = request; |
| 1963 effective_load_flags_ = request_->load_flags; | 2060 effective_load_flags_ = request_->load_flags; |
| 2061 method_ = request_->method; |
| 1964 | 2062 |
| 1965 if (cache_->mode() == DISABLE) | 2063 if (cache_->mode() == DISABLE) |
| 1966 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 2064 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| 1967 | 2065 |
| 1968 // Some headers imply load flags. The order here is significant. | 2066 // Some headers imply load flags. The order here is significant. |
| 1969 // | 2067 // |
| 1970 // LOAD_DISABLE_CACHE : no cache read or write | 2068 // LOAD_DISABLE_CACHE : no cache read or write |
| 1971 // LOAD_BYPASS_CACHE : no cache read | 2069 // LOAD_BYPASS_CACHE : no cache read |
| 1972 // LOAD_VALIDATE_CACHE : no cache read unless validation | 2070 // LOAD_VALIDATE_CACHE : no cache read unless validation |
| 1973 // | 2071 // |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2033 // a cache validation, since we don't know for sure which header the server | 2131 // a cache validation, since we don't know for sure which header the server |
| 2034 // will give us a response for (and they could be contradictory). | 2132 // will give us a response for (and they could be contradictory). |
| 2035 if (external_validation_error) { | 2133 if (external_validation_error) { |
| 2036 LOG(WARNING) << "Multiple or malformed validation headers found."; | 2134 LOG(WARNING) << "Multiple or malformed validation headers found."; |
| 2037 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 2135 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| 2038 } | 2136 } |
| 2039 | 2137 |
| 2040 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { | 2138 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { |
| 2041 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); | 2139 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); |
| 2042 partial_.reset(new PartialData); | 2140 partial_.reset(new PartialData); |
| 2043 if (request_->method == "GET" && partial_->Init(request_->extra_headers)) { | 2141 if (method_ == "GET" && partial_->Init(request_->extra_headers)) { |
| 2044 // We will be modifying the actual range requested to the server, so | 2142 // We will be modifying the actual range requested to the server, so |
| 2045 // let's remove the header here. | 2143 // let's remove the header here. |
| 2046 custom_request_.reset(new HttpRequestInfo(*request_)); | 2144 custom_request_.reset(new HttpRequestInfo(*request_)); |
| 2047 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); | 2145 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); |
| 2048 request_ = custom_request_.get(); | 2146 request_ = custom_request_.get(); |
| 2049 partial_->SetHeaders(custom_request_->extra_headers); | 2147 partial_->SetHeaders(custom_request_->extra_headers); |
| 2050 } else { | 2148 } else { |
| 2051 // The range is invalid or we cannot handle it properly. | 2149 // The range is invalid or we cannot handle it properly. |
| 2052 VLOG(1) << "Invalid byte range found."; | 2150 VLOG(1) << "Invalid byte range found."; |
| 2053 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 2151 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| 2054 partial_.reset(NULL); | 2152 partial_.reset(NULL); |
| 2055 } | 2153 } |
| 2056 } | 2154 } |
| 2155 restart_info_.cache_entry_status = cache_entry_status_; |
| 2057 } | 2156 } |
| 2058 | 2157 |
| 2059 bool HttpCache::Transaction::ShouldPassThrough() { | 2158 bool HttpCache::Transaction::ShouldPassThrough() { |
| 2060 // We may have a null disk_cache if there is an error we cannot recover from, | 2159 // We may have a null disk_cache if there is an error we cannot recover from, |
| 2061 // like not enough disk space, or sharing violations. | 2160 // like not enough disk space, or sharing violations. |
| 2062 if (!cache_->disk_cache_.get()) | 2161 if (!cache_->disk_cache_.get()) |
| 2063 return true; | 2162 return true; |
| 2064 | 2163 |
| 2065 if (effective_load_flags_ & LOAD_DISABLE_CACHE) | 2164 if (effective_load_flags_ & LOAD_DISABLE_CACHE) |
| 2066 return true; | 2165 return true; |
| 2067 | 2166 |
| 2068 if (request_->method == "GET" || request_->method == "HEAD") | 2167 if (method_ == "GET" || method_ == "HEAD") |
| 2069 return false; | 2168 return false; |
| 2070 | 2169 |
| 2071 if (request_->method == "POST" && request_->upload_data_stream && | 2170 if (method_ == "POST" && request_->upload_data_stream && |
| 2072 request_->upload_data_stream->identifier()) { | 2171 request_->upload_data_stream->identifier()) { |
| 2073 return false; | 2172 return false; |
| 2074 } | 2173 } |
| 2075 | 2174 |
| 2076 if (request_->method == "PUT" && request_->upload_data_stream) | 2175 if (method_ == "PUT" && request_->upload_data_stream) |
| 2077 return false; | 2176 return false; |
| 2078 | 2177 |
| 2079 if (request_->method == "DELETE") | 2178 if (method_ == "DELETE") |
| 2080 return false; | 2179 return false; |
| 2081 | 2180 |
| 2082 return true; | 2181 return true; |
| 2083 } | 2182 } |
| 2084 | 2183 |
| 2085 int HttpCache::Transaction::BeginCacheRead() { | 2184 int HttpCache::Transaction::BeginCacheRead() { |
| 2086 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. | 2185 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. |
| 2087 // TODO(jkarlin): Either handle this case or DCHECK. | 2186 // TODO(jkarlin): Either handle this case or DCHECK. |
| 2088 if (response_.headers->response_code() == 206 || partial_) { | 2187 if (response_.headers->response_code() == 206 || partial_) { |
| 2089 NOTREACHED(); | 2188 NOTREACHED(); |
| 2090 TransitionToState(STATE_NONE); | 2189 TransitionToState(STATE_FINISH_HEADERS); |
| 2091 return ERR_CACHE_MISS; | 2190 return ERR_CACHE_MISS; |
| 2092 } | 2191 } |
| 2093 | 2192 |
| 2094 // We don't have the whole resource. | 2193 // We don't have the whole resource. |
| 2095 if (truncated_) { | 2194 if (truncated_) { |
| 2096 TransitionToState(STATE_NONE); | 2195 TransitionToState(STATE_FINISH_HEADERS); |
| 2097 return ERR_CACHE_MISS; | 2196 return ERR_CACHE_MISS; |
| 2098 } | 2197 } |
| 2099 | 2198 |
| 2100 if (RequiresValidation()) { | 2199 if (RequiresValidation()) { |
| 2101 TransitionToState(STATE_NONE); | 2200 TransitionToState(STATE_FINISH_HEADERS); |
| 2102 return ERR_CACHE_MISS; | 2201 return ERR_CACHE_MISS; |
| 2103 } | 2202 } |
| 2104 | 2203 |
| 2105 if (request_->method == "HEAD") | 2204 if (method_ == "HEAD") |
| 2106 FixHeadersForHead(); | 2205 FixHeadersForHead(); |
| 2107 | 2206 |
| 2108 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 2207 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 2109 TransitionToState(STATE_CACHE_READ_METADATA); | 2208 TransitionToState(STATE_CACHE_READ_METADATA); |
| 2110 else | 2209 else |
| 2111 TransitionToState(STATE_NONE); | 2210 TransitionToState(STATE_FINISH_HEADERS); |
| 2112 | 2211 |
| 2113 return OK; | 2212 return OK; |
| 2114 } | 2213 } |
| 2115 | 2214 |
| 2116 int HttpCache::Transaction::BeginCacheValidation() { | 2215 int HttpCache::Transaction::BeginCacheValidation() { |
| 2117 DCHECK_EQ(mode_, READ_WRITE); | 2216 DCHECK_EQ(mode_, READ_WRITE); |
| 2118 | 2217 |
| 2119 bool skip_validation = !RequiresValidation(); | 2218 bool skip_validation = !RequiresValidation(); |
| 2120 | 2219 |
| 2121 if (request_->method == "HEAD" && | 2220 if (method_ == "HEAD" && |
| 2122 (truncated_ || response_.headers->response_code() == 206)) { | 2221 (truncated_ || response_.headers->response_code() == 206)) { |
| 2123 DCHECK(!partial_); | 2222 DCHECK(!partial_); |
| 2124 if (skip_validation) | 2223 if (skip_validation) |
| 2125 return SetupEntryForRead(); | 2224 return SetupEntryForRead(); |
| 2126 | 2225 |
| 2127 // Bail out! | 2226 // Bail out! |
| 2128 TransitionToState(STATE_SEND_REQUEST); | 2227 TransitionToState(STATE_SEND_REQUEST); |
| 2129 mode_ = NONE; | 2228 mode_ = NONE; |
| 2130 return OK; | 2229 return OK; |
| 2131 } | 2230 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2169 } | 2268 } |
| 2170 | 2269 |
| 2171 int HttpCache::Transaction::BeginPartialCacheValidation() { | 2270 int HttpCache::Transaction::BeginPartialCacheValidation() { |
| 2172 DCHECK_EQ(mode_, READ_WRITE); | 2271 DCHECK_EQ(mode_, READ_WRITE); |
| 2173 | 2272 |
| 2174 if (response_.headers->response_code() != 206 && !partial_ && !truncated_) | 2273 if (response_.headers->response_code() != 206 && !partial_ && !truncated_) |
| 2175 return BeginCacheValidation(); | 2274 return BeginCacheValidation(); |
| 2176 | 2275 |
| 2177 // Partial requests should not be recorded in histograms. | 2276 // Partial requests should not be recorded in histograms. |
| 2178 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); | 2277 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); |
| 2179 if (request_->method == "HEAD") | 2278 if (method_ == "HEAD") |
| 2180 return BeginCacheValidation(); | 2279 return BeginCacheValidation(); |
| 2181 | 2280 |
| 2182 if (!range_requested_) { | 2281 if (!range_requested_) { |
| 2183 // The request is not for a range, but we have stored just ranges. | 2282 // The request is not for a range, but we have stored just ranges. |
| 2184 | 2283 |
| 2185 partial_.reset(new PartialData()); | 2284 partial_.reset(new PartialData()); |
| 2186 partial_->SetHeaders(request_->extra_headers); | 2285 partial_->SetHeaders(request_->extra_headers); |
| 2187 if (!custom_request_.get()) { | 2286 if (!custom_request_.get()) { |
| 2188 custom_request_.reset(new HttpRequestInfo(*request_)); | 2287 custom_request_.reset(new HttpRequestInfo(*request_)); |
| 2189 request_ = custom_request_.get(); | 2288 request_ = custom_request_.get(); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2307 // The first use of a resource after prefetch within a short window skips | 2406 // The first use of a resource after prefetch within a short window skips |
| 2308 // validation. | 2407 // validation. |
| 2309 return false; | 2408 return false; |
| 2310 } | 2409 } |
| 2311 | 2410 |
| 2312 if (effective_load_flags_ & LOAD_VALIDATE_CACHE) { | 2411 if (effective_load_flags_ & LOAD_VALIDATE_CACHE) { |
| 2313 validation_cause_ = VALIDATION_CAUSE_VALIDATE_FLAG; | 2412 validation_cause_ = VALIDATION_CAUSE_VALIDATE_FLAG; |
| 2314 return true; | 2413 return true; |
| 2315 } | 2414 } |
| 2316 | 2415 |
| 2317 if (request_->method == "PUT" || request_->method == "DELETE") | 2416 if (method_ == "PUT" || method_ == "DELETE") |
| 2318 return true; | 2417 return true; |
| 2319 | 2418 |
| 2320 bool validation_required_by_headers = response_.headers->RequiresValidation( | 2419 bool validation_required_by_headers = response_.headers->RequiresValidation( |
| 2321 response_.request_time, response_.response_time, cache_->clock_->Now()); | 2420 response_.request_time, response_.response_time, cache_->clock_->Now()); |
| 2322 | 2421 |
| 2323 if (validation_required_by_headers) { | 2422 if (validation_required_by_headers) { |
| 2324 HttpResponseHeaders::FreshnessLifetimes lifetimes = | 2423 HttpResponseHeaders::FreshnessLifetimes lifetimes = |
| 2325 response_.headers->GetFreshnessLifetimes(response_.response_time); | 2424 response_.headers->GetFreshnessLifetimes(response_.response_time); |
| 2326 if (lifetimes.freshness == base::TimeDelta()) { | 2425 if (lifetimes.freshness == base::TimeDelta()) { |
| 2327 validation_cause_ = VALIDATION_CAUSE_ZERO_FRESHNESS; | 2426 validation_cause_ = VALIDATION_CAUSE_ZERO_FRESHNESS; |
| 2328 } else { | 2427 } else { |
| 2329 validation_cause_ = VALIDATION_CAUSE_STALE; | 2428 validation_cause_ = VALIDATION_CAUSE_STALE; |
| 2330 stale_entry_freshness_ = lifetimes.freshness; | 2429 stale_entry_freshness_ = lifetimes.freshness; |
| 2331 stale_entry_age_ = response_.headers->GetCurrentAge( | 2430 stale_entry_age_ = response_.headers->GetCurrentAge( |
| 2332 response_.request_time, response_.response_time, | 2431 response_.request_time, response_.response_time, |
| 2333 cache_->clock_->Now()); | 2432 cache_->clock_->Now()); |
| 2334 } | 2433 } |
| 2335 } | 2434 } |
| 2336 | 2435 |
| 2337 return validation_required_by_headers; | 2436 return validation_required_by_headers; |
| 2338 } | 2437 } |
| 2339 | 2438 |
| 2340 bool HttpCache::Transaction::ConditionalizeRequest() { | 2439 bool HttpCache::Transaction::ConditionalizeRequest() { |
| 2341 DCHECK(response_.headers.get()); | 2440 DCHECK(response_.headers.get()); |
| 2342 | 2441 |
| 2343 if (request_->method == "PUT" || request_->method == "DELETE") | 2442 if (method_ == "PUT" || method_ == "DELETE") |
| 2344 return false; | 2443 return false; |
| 2345 | 2444 |
| 2346 // This only makes sense for cached 200 or 206 responses. | 2445 // This only makes sense for cached 200 or 206 responses. |
| 2347 if (response_.headers->response_code() != 200 && | 2446 if (response_.headers->response_code() != 200 && |
| 2348 response_.headers->response_code() != 206) { | 2447 response_.headers->response_code() != 206) { |
| 2349 return false; | 2448 return false; |
| 2350 } | 2449 } |
| 2351 | 2450 |
| 2352 if (fail_conditionalization_for_test_) | 2451 if (fail_conditionalization_for_test_) |
| 2353 return false; | 2452 return false; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2427 // | 2526 // |
| 2428 // WARNING: Whenever this code returns false, it has to make sure that the next | 2527 // WARNING: Whenever this code returns false, it has to make sure that the next |
| 2429 // time it is called it will return true so that we don't keep retrying the | 2528 // time it is called it will return true so that we don't keep retrying the |
| 2430 // request. | 2529 // request. |
| 2431 bool HttpCache::Transaction::ValidatePartialResponse() { | 2530 bool HttpCache::Transaction::ValidatePartialResponse() { |
| 2432 const HttpResponseHeaders* headers = new_response_->headers.get(); | 2531 const HttpResponseHeaders* headers = new_response_->headers.get(); |
| 2433 int response_code = headers->response_code(); | 2532 int response_code = headers->response_code(); |
| 2434 bool partial_response = (response_code == 206); | 2533 bool partial_response = (response_code == 206); |
| 2435 handling_206_ = false; | 2534 handling_206_ = false; |
| 2436 | 2535 |
| 2437 if (!entry_ || request_->method != "GET") | 2536 if (!entry_ || method_ != "GET") |
| 2438 return true; | 2537 return true; |
| 2439 | 2538 |
| 2440 if (invalid_range_) { | 2539 if (invalid_range_) { |
| 2441 // We gave up trying to match this request with the stored data. If the | 2540 // We gave up trying to match this request with the stored data. If the |
| 2442 // server is ok with the request, delete the entry, otherwise just ignore | 2541 // server is ok with the request, delete the entry, otherwise just ignore |
| 2443 // this request | 2542 // this request |
| 2444 DCHECK(!reading_); | 2543 DCHECK(!reading_); |
| 2445 if (partial_response || response_code == 200) { | 2544 if (partial_response || response_code == 200) { |
| 2446 DoomPartialEntry(true); | 2545 DoomPartialEntry(true); |
| 2447 mode_ = NONE; | 2546 mode_ = NONE; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2534 | 2633 |
| 2535 void HttpCache::Transaction::IgnoreRangeRequest() { | 2634 void HttpCache::Transaction::IgnoreRangeRequest() { |
| 2536 // We have a problem. We may or may not be reading already (in which case we | 2635 // We have a problem. We may or may not be reading already (in which case we |
| 2537 // returned the headers), but we'll just pretend that this request is not | 2636 // returned the headers), but we'll just pretend that this request is not |
| 2538 // using the cache and see what happens. Most likely this is the first | 2637 // using the cache and see what happens. Most likely this is the first |
| 2539 // response from the server (it's not changing its mind midway, right?). | 2638 // response from the server (it's not changing its mind midway, right?). |
| 2540 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); | 2639 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); |
| 2541 if (mode_ & WRITE) | 2640 if (mode_ & WRITE) |
| 2542 DoneWritingToEntry(mode_ != WRITE); | 2641 DoneWritingToEntry(mode_ != WRITE); |
| 2543 else if (mode_ & READ && entry_) | 2642 else if (mode_ & READ && entry_) |
| 2544 cache_->DoneReadingFromEntry(entry_, this); | 2643 cache_->DoneWithEntry(entry_, this, false /* process_cancel */, |
| 2644 partial_ != nullptr); |
| 2545 | 2645 |
| 2546 partial_.reset(NULL); | 2646 partial_.reset(NULL); |
| 2547 entry_ = NULL; | 2647 entry_ = NULL; |
| 2548 mode_ = NONE; | 2648 mode_ = NONE; |
| 2549 } | 2649 } |
| 2550 | 2650 |
| 2551 void HttpCache::Transaction::FixHeadersForHead() { | 2651 void HttpCache::Transaction::FixHeadersForHead() { |
| 2552 if (response_.headers->response_code() == 206) { | 2652 if (response_.headers->response_code() == 206) { |
| 2553 response_.headers->RemoveHeader("Content-Range"); | 2653 response_.headers->RemoveHeader("Content-Range"); |
| 2554 response_.headers->ReplaceStatusLine("HTTP/1.1 200 OK"); | 2654 response_.headers->ReplaceStatusLine("HTTP/1.1 200 OK"); |
| 2555 } | 2655 } |
| 2556 } | 2656 } |
| 2557 | 2657 |
| 2558 int HttpCache::Transaction::SetupEntryForRead() { | 2658 int HttpCache::Transaction::SetupEntryForRead() { |
| 2559 if (network_trans_) | 2659 if (network_trans_) |
| 2560 ResetNetworkTransaction(); | 2660 ResetNetworkTransaction(); |
| 2561 if (partial_) { | 2661 if (partial_) { |
| 2562 if (truncated_ || is_sparse_ || !invalid_range_) { | 2662 if (truncated_ || is_sparse_ || !invalid_range_) { |
| 2563 // We are going to return the saved response headers to the caller, so | 2663 // We are going to return the saved response headers to the caller, so |
| 2564 // we may need to adjust them first. | 2664 // we may need to adjust them first. |
| 2565 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); | 2665 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); |
| 2566 return OK; | 2666 return OK; |
| 2567 } else { | 2667 } else { |
| 2568 partial_.reset(); | 2668 partial_.reset(); |
| 2569 } | 2669 } |
| 2570 } | 2670 } |
| 2571 cache_->ConvertWriterToReader(entry_); | 2671 |
| 2572 mode_ = READ; | 2672 mode_ = READ; |
| 2573 | 2673 |
| 2574 if (request_->method == "HEAD") | 2674 if (method_ == "HEAD") |
| 2575 FixHeadersForHead(); | 2675 FixHeadersForHead(); |
| 2576 | 2676 |
| 2577 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 2677 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 2578 TransitionToState(STATE_CACHE_READ_METADATA); | 2678 TransitionToState(STATE_CACHE_READ_METADATA); |
| 2579 else | 2679 else |
| 2580 TransitionToState(STATE_NONE); | 2680 TransitionToState(STATE_FINISH_HEADERS); |
| 2581 return OK; | 2681 return OK; |
| 2582 } | 2682 } |
| 2583 | 2683 |
| 2584 int HttpCache::Transaction::WriteToEntry(int index, int offset, | 2684 int HttpCache::Transaction::WriteToEntry(int index, int offset, |
| 2585 IOBuffer* data, int data_len, | 2685 IOBuffer* data, int data_len, |
| 2586 const CompletionCallback& callback) { | 2686 const CompletionCallback& callback) { |
| 2587 if (!entry_) | 2687 if (!entry_) |
| 2588 return data_len; | 2688 return data_len; |
| 2589 | 2689 |
| 2590 int rv = 0; | 2690 int rv = 0; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2649 } | 2749 } |
| 2650 return OK; | 2750 return OK; |
| 2651 } | 2751 } |
| 2652 | 2752 |
| 2653 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2753 void HttpCache::Transaction::DoneWritingToEntry(bool success) { |
| 2654 if (!entry_) | 2754 if (!entry_) |
| 2655 return; | 2755 return; |
| 2656 | 2756 |
| 2657 RecordHistograms(); | 2757 RecordHistograms(); |
| 2658 | 2758 |
| 2659 cache_->DoneWritingToEntry(entry_, success); | 2759 cache_->DoneWritingToEntry(entry_, success, this); |
| 2660 entry_ = NULL; | 2760 entry_ = NULL; |
| 2661 mode_ = NONE; // switch to 'pass through' mode | 2761 mode_ = NONE; // switch to 'pass through' mode |
| 2662 } | 2762 } |
| 2663 | 2763 |
| 2664 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2764 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
| 2665 DLOG(ERROR) << "ReadData failed: " << result; | 2765 DLOG(ERROR) << "ReadData failed: " << result; |
| 2666 const int result_for_histogram = std::max(0, -result); | 2766 const int result_for_histogram = std::max(0, -result); |
| 2667 if (restart) { | 2767 if (restart) { |
| 2668 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", | 2768 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", |
| 2669 result_for_histogram); | 2769 result_for_histogram); |
| 2670 } else { | 2770 } else { |
| 2671 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", | 2771 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", |
| 2672 result_for_histogram); | 2772 result_for_histogram); |
| 2673 } | 2773 } |
| 2674 | 2774 |
| 2675 // Avoid using this entry in the future. | 2775 // Avoid using this entry in the future. |
| 2676 if (cache_.get()) | 2776 if (cache_.get()) |
| 2677 cache_->DoomActiveEntry(cache_key_); | 2777 cache_->DoomActiveEntry(cache_key_); |
| 2678 | 2778 |
| 2679 if (restart) { | 2779 if (restart) { |
| 2680 DCHECK(!reading_); | 2780 DCHECK(!reading_); |
| 2681 DCHECK(!network_trans_.get()); | 2781 DCHECK(!network_trans_.get()); |
| 2682 cache_->DoneWithEntry(entry_, this, false); | 2782 cache_->DoneWithEntry(entry_, this, false /* process_cancel */, |
| 2783 partial_ != nullptr); |
| 2683 entry_ = NULL; | 2784 entry_ = NULL; |
| 2684 is_sparse_ = false; | 2785 is_sparse_ = false; |
| 2685 partial_.reset(); | 2786 partial_.reset(); |
| 2686 TransitionToState(STATE_GET_BACKEND); | 2787 TransitionToState(STATE_GET_BACKEND); |
| 2687 return OK; | 2788 return OK; |
| 2688 } | 2789 } |
| 2689 | 2790 |
| 2690 TransitionToState(STATE_NONE); | 2791 TransitionToState(STATE_NONE); |
| 2691 return ERR_CACHE_READ_FAILURE; | 2792 return ERR_CACHE_READ_FAILURE; |
| 2692 } | 2793 } |
| 2693 | 2794 |
| 2694 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { | 2795 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { |
| 2695 if (entry_lock_waiting_since_ != start_time) | 2796 if (entry_lock_waiting_since_ != start_time) |
| 2696 return; | 2797 return; |
| 2697 | 2798 |
| 2698 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); | 2799 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); |
| 2699 | 2800 |
| 2700 if (!cache_) | 2801 if (!cache_) |
| 2701 return; | 2802 return; |
| 2702 | 2803 |
| 2703 cache_->RemovePendingTransaction(this); | 2804 cache_->RemovePendingTransaction(this); |
| 2704 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); | 2805 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); |
| 2705 } | 2806 } |
| 2706 | 2807 |
| 2707 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { | 2808 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { |
| 2708 DVLOG(2) << "DoomPartialEntry"; | 2809 DVLOG(2) << "DoomPartialEntry"; |
| 2709 int rv = cache_->DoomEntry(cache_key_, NULL); | 2810 int rv = cache_->DoomEntry(cache_key_, NULL); |
| 2710 DCHECK_EQ(OK, rv); | 2811 DCHECK_EQ(OK, rv); |
| 2711 cache_->DoneWithEntry(entry_, this, false); | 2812 cache_->DoneWithEntry(entry_, this, false /* process_cancel */, |
| 2813 partial_ != nullptr); |
| 2712 entry_ = NULL; | 2814 entry_ = NULL; |
| 2713 is_sparse_ = false; | 2815 is_sparse_ = false; |
| 2714 truncated_ = false; | 2816 truncated_ = false; |
| 2715 if (delete_object) | 2817 if (delete_object) |
| 2716 partial_.reset(NULL); | 2818 partial_.reset(NULL); |
| 2717 } | 2819 } |
| 2718 | 2820 |
| 2719 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { | 2821 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { |
| 2720 partial_->OnNetworkReadCompleted(result); | 2822 partial_->OnNetworkReadCompleted(result); |
| 2721 | 2823 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2797 // Accept-Ranges: none.......... 0.4% | 2899 // Accept-Ranges: none.......... 0.4% |
| 2798 // Strong Validator............. 50% | 2900 // Strong Validator............. 50% |
| 2799 // Strong Validator + ranges.... 24% | 2901 // Strong Validator + ranges.... 24% |
| 2800 // Strong Validator + CL........ 49% | 2902 // Strong Validator + CL........ 49% |
| 2801 // | 2903 // |
| 2802 bool HttpCache::Transaction::CanResume(bool has_data) { | 2904 bool HttpCache::Transaction::CanResume(bool has_data) { |
| 2803 // Double check that there is something worth keeping. | 2905 // Double check that there is something worth keeping. |
| 2804 if (has_data && !entry_->disk_entry->GetDataSize(kResponseContentIndex)) | 2906 if (has_data && !entry_->disk_entry->GetDataSize(kResponseContentIndex)) |
| 2805 return false; | 2907 return false; |
| 2806 | 2908 |
| 2807 if (request_->method != "GET") | 2909 if (method_ != "GET") |
| 2808 return false; | 2910 return false; |
| 2809 | 2911 |
| 2810 // Note that if this is a 206, content-length was already fixed after calling | 2912 // Note that if this is a 206, content-length was already fixed after calling |
| 2811 // PartialData::ResponseHeadersOK(). | 2913 // PartialData::ResponseHeadersOK(). |
| 2812 if (response_.headers->GetContentLength() <= 0 || | 2914 if (response_.headers->GetContentLength() <= 0 || |
| 2813 response_.headers->HasHeaderValue("Accept-Ranges", "none") || | 2915 response_.headers->HasHeaderValue("Accept-Ranges", "none") || |
| 2814 !response_.headers->HasStrongValidators()) { | 2916 !response_.headers->HasStrongValidators()) { |
| 2815 return false; | 2917 return false; |
| 2816 } | 2918 } |
| 2817 | 2919 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2846 response_.cache_entry_status = cache_entry_status_; | 2948 response_.cache_entry_status = cache_entry_status_; |
| 2847 if (auth_response_.headers.get()) { | 2949 if (auth_response_.headers.get()) { |
| 2848 auth_response_.cache_entry_status = cache_entry_status_; | 2950 auth_response_.cache_entry_status = cache_entry_status_; |
| 2849 } | 2951 } |
| 2850 } | 2952 } |
| 2851 | 2953 |
| 2852 void HttpCache::Transaction::RecordHistograms() { | 2954 void HttpCache::Transaction::RecordHistograms() { |
| 2853 DCHECK_NE(CacheEntryStatus::ENTRY_UNDEFINED, cache_entry_status_); | 2955 DCHECK_NE(CacheEntryStatus::ENTRY_UNDEFINED, cache_entry_status_); |
| 2854 if (!cache_.get() || !cache_->GetCurrentBackend() || | 2956 if (!cache_.get() || !cache_->GetCurrentBackend() || |
| 2855 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || | 2957 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || |
| 2856 cache_->mode() != NORMAL || request_->method != "GET") { | 2958 cache_->mode() != NORMAL || method_ != "GET") { |
| 2857 return; | 2959 return; |
| 2858 } | 2960 } |
| 2859 | 2961 |
| 2860 bool validation_request = | 2962 bool validation_request = |
| 2861 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || | 2963 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || |
| 2862 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED; | 2964 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED; |
| 2863 | 2965 |
| 2864 bool stale_request = | 2966 bool stale_request = |
| 2865 validation_cause_ == VALIDATION_CAUSE_STALE && | 2967 validation_cause_ == VALIDATION_CAUSE_STALE && |
| 2866 (validation_request || | 2968 (validation_request || |
| 2867 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); | 2969 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); |
| 2868 int64_t freshness_periods_since_last_used = 0; | 2970 int64_t freshness_periods_since_last_used = 0; |
| 2869 | 2971 |
| 2870 if (stale_request) { | 2972 if (stale_request && !open_entry_last_used_.is_null()) { |
| 2973 // Note that we are not able to capture those transactions' histograms which |
| 2974 // when added to entry, the response was being written by another |
| 2975 // transaction because getting the last used timestamp might lead to a data |
| 2976 // race in that case. TODO(crbug.com/713354). |
| 2977 |
| 2871 // For stale entries, record how many freshness periods have elapsed since | 2978 // For stale entries, record how many freshness periods have elapsed since |
| 2872 // the entry was last used. | 2979 // the entry was last used. |
| 2873 DCHECK(!open_entry_last_used_.is_null()); | |
| 2874 DCHECK(!stale_entry_freshness_.is_zero()); | 2980 DCHECK(!stale_entry_freshness_.is_zero()); |
| 2875 base::TimeDelta time_since_use = base::Time::Now() - open_entry_last_used_; | 2981 base::TimeDelta time_since_use = base::Time::Now() - open_entry_last_used_; |
| 2876 freshness_periods_since_last_used = | 2982 freshness_periods_since_last_used = |
| 2877 (time_since_use * 1000) / stale_entry_freshness_; | 2983 (time_since_use * 1000) / stale_entry_freshness_; |
| 2878 | 2984 |
| 2879 if (validation_request) { | 2985 if (validation_request) { |
| 2880 int64_t age_in_freshness_periods = | 2986 int64_t age_in_freshness_periods = |
| 2881 (stale_entry_age_ * 100) / stale_entry_freshness_; | 2987 (stale_entry_age_ * 100) / stale_entry_freshness_; |
| 2882 if (cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED) { | 2988 if (cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED) { |
| 2883 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Validated.Age", | 2989 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Validated.Age", |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2896 } | 3002 } |
| 2897 } | 3003 } |
| 2898 | 3004 |
| 2899 std::string mime_type; | 3005 std::string mime_type; |
| 2900 HttpResponseHeaders* response_headers = GetResponseInfo()->headers.get(); | 3006 HttpResponseHeaders* response_headers = GetResponseInfo()->headers.get(); |
| 2901 if (response_headers && response_headers->GetMimeType(&mime_type)) { | 3007 if (response_headers && response_headers->GetMimeType(&mime_type)) { |
| 2902 // Record the cache pattern by resource type. The type is inferred by | 3008 // Record the cache pattern by resource type. The type is inferred by |
| 2903 // response header mime type, which could be incorrect, so this is just an | 3009 // response header mime type, which could be incorrect, so this is just an |
| 2904 // estimate. | 3010 // estimate. |
| 2905 if (mime_type == "text/html" && | 3011 if (mime_type == "text/html" && |
| 2906 (request_->load_flags & LOAD_MAIN_FRAME_DEPRECATED)) { | 3012 (effective_load_flags_ & LOAD_MAIN_FRAME_DEPRECATED)) { |
| 2907 CACHE_STATUS_HISTOGRAMS(".MainFrameHTML"); | 3013 CACHE_STATUS_HISTOGRAMS(".MainFrameHTML"); |
| 2908 } else if (mime_type == "text/html") { | 3014 } else if (mime_type == "text/html") { |
| 2909 CACHE_STATUS_HISTOGRAMS(".NonMainFrameHTML"); | 3015 CACHE_STATUS_HISTOGRAMS(".NonMainFrameHTML"); |
| 2910 } else if (mime_type == "text/css") { | 3016 } else if (mime_type == "text/css") { |
| 2911 CACHE_STATUS_HISTOGRAMS(".CSS"); | 3017 CACHE_STATUS_HISTOGRAMS(".CSS"); |
| 2912 } else if (base::StartsWith(mime_type, "image/", | 3018 } else if (base::StartsWith(mime_type, "image/", |
| 2913 base::CompareCase::SENSITIVE)) { | 3019 base::CompareCase::SENSITIVE)) { |
| 2914 int64_t content_length = response_headers->GetContentLength(); | 3020 int64_t content_length = response_headers->GetContentLength(); |
| 2915 if (content_length >= 0 && content_length < 100) { | 3021 if (content_length >= 0 && content_length < 100) { |
| 2916 CACHE_STATUS_HISTOGRAMS(".TinyImage"); | 3022 CACHE_STATUS_HISTOGRAMS(".TinyImage"); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2936 | 3042 |
| 2937 CACHE_STATUS_HISTOGRAMS(""); | 3043 CACHE_STATUS_HISTOGRAMS(""); |
| 2938 | 3044 |
| 2939 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { | 3045 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { |
| 2940 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", | 3046 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", |
| 2941 validation_cause_, VALIDATION_CAUSE_MAX); | 3047 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2942 } | 3048 } |
| 2943 | 3049 |
| 2944 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) | 3050 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) |
| 2945 return; | 3051 return; |
| 2946 DCHECK(!range_requested_); | 3052 |
| 3053 DCHECK(!range_requested_) << "Cache entry status " << cache_entry_status_; |
| 2947 DCHECK(!first_cache_access_since_.is_null()); | 3054 DCHECK(!first_cache_access_since_.is_null()); |
| 2948 | 3055 |
| 2949 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; | 3056 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2950 | 3057 |
| 2951 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); | 3058 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2952 | 3059 |
| 2953 bool did_send_request = !send_request_since_.is_null(); | 3060 bool did_send_request = !send_request_since_.is_null(); |
| 2954 DCHECK( | 3061 DCHECK( |
| 2955 (did_send_request && | 3062 (did_send_request && |
| 2956 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || | 3063 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3017 } | 3124 } |
| 3018 | 3125 |
| 3019 void HttpCache::Transaction::TransitionToState(State state) { | 3126 void HttpCache::Transaction::TransitionToState(State state) { |
| 3020 // Ensure that the state is only set once per Do* state. | 3127 // Ensure that the state is only set once per Do* state. |
| 3021 DCHECK(in_do_loop_); | 3128 DCHECK(in_do_loop_); |
| 3022 DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state; | 3129 DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state; |
| 3023 next_state_ = state; | 3130 next_state_ = state; |
| 3024 } | 3131 } |
| 3025 | 3132 |
| 3026 } // namespace net | 3133 } // namespace net |
| OLD | NEW |