Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: net/http/http_cache_transaction.cc

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

Powered by Google App Engine
This is Rietveld 408576698