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

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

Issue 2847653002: Revert of HttpCache::Transaction layer allowing parallel validation (Closed)
Patch Set: Created 3 years, 7 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
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | net/http/http_cache_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 149
150 HttpCache::Transaction::Transaction(RequestPriority priority, HttpCache* cache) 150 HttpCache::Transaction::Transaction(RequestPriority priority, HttpCache* cache)
151 : next_state_(STATE_NONE), 151 : next_state_(STATE_NONE),
152 request_(NULL), 152 request_(NULL),
153 priority_(priority), 153 priority_(priority),
154 cache_(cache->GetWeakPtr()), 154 cache_(cache->GetWeakPtr()),
155 entry_(NULL), 155 entry_(NULL),
156 new_entry_(NULL), 156 new_entry_(NULL),
157 new_response_(NULL), 157 new_response_(NULL),
158 mode_(NONE), 158 mode_(NONE),
159 original_mode_(NONE),
160 reading_(false), 159 reading_(false),
161 invalid_range_(false), 160 invalid_range_(false),
162 truncated_(false), 161 truncated_(false),
163 is_sparse_(false), 162 is_sparse_(false),
164 range_requested_(false), 163 range_requested_(false),
165 handling_206_(false), 164 handling_206_(false),
166 cache_pending_(false), 165 cache_pending_(false),
167 done_reading_(false), 166 done_reading_(false),
168 vary_mismatch_(false), 167 vary_mismatch_(false),
169 couldnt_conditionalize_request_(false), 168 couldnt_conditionalize_request_(false),
(...skipping 20 matching lines...) Expand all
190 } 189 }
191 190
192 HttpCache::Transaction::~Transaction() { 191 HttpCache::Transaction::~Transaction() {
193 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); 192 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction");
194 // 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_
195 // after this point. 194 // after this point.
196 callback_.Reset(); 195 callback_.Reset();
197 196
198 if (cache_) { 197 if (cache_) {
199 if (entry_) { 198 if (entry_) {
200 bool writing_incomplete = cache_->IsTransactionWritingIncomplete( 199 bool cancel_request = reading_ && response_.headers.get();
201 entry_, this, request_->method); 200 if (cancel_request) {
202 if (writing_incomplete && partial_) 201 if (partial_) {
203 entry_->disk_entry->CancelSparseIO(); 202 entry_->disk_entry->CancelSparseIO();
203 } else {
204 cancel_request &= (response_.headers->response_code() == 200);
205 }
206 }
204 207
205 cache_->DoneWithEntry(entry_, this, writing_incomplete); 208 cache_->DoneWithEntry(entry_, this, cancel_request);
206 } else if (cache_pending_) { 209 } else if (cache_pending_) {
207 cache_->RemovePendingTransaction(this); 210 cache_->RemovePendingTransaction(this);
208 } 211 }
209 } 212 }
210 } 213 }
211 214
212 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, 215 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len,
213 const CompletionCallback& callback) { 216 const CompletionCallback& callback) {
214 DCHECK(buf); 217 DCHECK(buf);
215 DCHECK_GT(buf_len, 0); 218 DCHECK_GT(buf_len, 0);
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 ConnectionAttempts* out) const { 558 ConnectionAttempts* out) const {
556 ConnectionAttempts new_connection_attempts; 559 ConnectionAttempts new_connection_attempts;
557 if (network_trans_) 560 if (network_trans_)
558 network_trans_->GetConnectionAttempts(&new_connection_attempts); 561 network_trans_->GetConnectionAttempts(&new_connection_attempts);
559 562
560 out->swap(new_connection_attempts); 563 out->swap(new_connection_attempts);
561 out->insert(out->begin(), old_connection_attempts_.begin(), 564 out->insert(out->begin(), old_connection_attempts_.begin(),
562 old_connection_attempts_.end()); 565 old_connection_attempts_.end());
563 } 566 }
564 567
565 void HttpCache::Transaction::SetValidatingCannotProceed() {
566 DCHECK(!reading_);
567 next_state_ = STATE_HEADERS_PHASE_CANNOT_PROCEED;
568 entry_ = nullptr;
569 }
570
571 size_t HttpCache::Transaction::EstimateMemoryUsage() const { 568 size_t HttpCache::Transaction::EstimateMemoryUsage() const {
572 // TODO(xunjieli): Consider improving the coverage. crbug.com/669108. 569 // TODO(xunjieli): Consider improving the coverage. crbug.com/669108.
573 return 0; 570 return 0;
574 } 571 }
575 572
576 //----------------------------------------------------------------------------- 573 //-----------------------------------------------------------------------------
577 574
578 // A few common patterns: (Foo* means Foo -> FooComplete) 575 // A few common patterns: (Foo* means Foo -> FooComplete)
579 // 576 //
580 // 1. Not-cached entry: 577 // 1. Not-cached entry:
581 // Start(): 578 // Start():
582 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> 579 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* ->
583 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> 580 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse ->
584 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> 581 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* ->
585 // PartialHeadersReceived -> FinishHeaders* 582 // PartialHeadersReceived
586 // 583 //
587 // Read(): 584 // Read():
588 // NetworkRead* -> CacheWriteData* 585 // NetworkRead* -> CacheWriteData*
589 // 586 //
590 // 2. Cached entry, no validation: 587 // 2. Cached entry, no validation:
591 // Start(): 588 // Start():
592 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 589 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
593 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 590 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
594 // BeginCacheValidation() -> SetupEntryForRead() -> FinishHeaders* 591 // BeginCacheValidation() -> SetupEntryForRead()
595 // 592 //
596 // Read(): 593 // Read():
597 // CacheReadData* 594 // CacheReadData*
598 // 595 //
599 // 3. Cached entry, validation (304): 596 // 3. Cached entry, validation (304):
600 // Start(): 597 // Start():
601 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 598 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
602 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 599 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
603 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> 600 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
604 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> 601 // UpdateCachedResponse -> CacheWriteUpdatedResponse* ->
605 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> 602 // UpdateCachedResponseComplete -> OverwriteCachedResponse ->
606 // PartialHeadersReceived -> FinishHeaders* 603 // PartialHeadersReceived
607 // 604 //
608 // Read(): 605 // Read():
609 // CacheReadData* 606 // CacheReadData*
610 // 607 //
611 // 4. Cached entry, validation and replace (200): 608 // 4. Cached entry, validation and replace (200):
612 // Start(): 609 // Start():
613 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 610 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
614 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 611 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
615 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> 612 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
616 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> 613 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* ->
617 // TruncateCachedMetadata* -> PartialHeadersReceived -> FinishHeaders* 614 // TruncateCachedMetadata* -> PartialHeadersReceived
618 // 615 //
619 // Read(): 616 // Read():
620 // NetworkRead* -> CacheWriteData* 617 // NetworkRead* -> CacheWriteData*
621 // 618 //
622 // 5. Sparse entry, partially cached, byte range request: 619 // 5. Sparse entry, partially cached, byte range request:
623 // Start(): 620 // Start():
624 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 621 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
625 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 622 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
626 // CacheQueryData* -> ValidateEntryHeadersAndContinue() -> 623 // CacheQueryData* -> ValidateEntryHeadersAndContinue() ->
627 // StartPartialCacheValidation -> CompletePartialCacheValidation -> 624 // StartPartialCacheValidation -> CompletePartialCacheValidation ->
628 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> 625 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
629 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> 626 // UpdateCachedResponse -> CacheWriteUpdatedResponse* ->
630 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> 627 // UpdateCachedResponseComplete -> OverwriteCachedResponse ->
631 // PartialHeadersReceived -> FinishHeaders* 628 // PartialHeadersReceived
632 // 629 //
633 // Read() 1: 630 // Read() 1:
634 // NetworkRead* -> CacheWriteData* 631 // NetworkRead* -> CacheWriteData*
635 // 632 //
636 // Read() 2: 633 // Read() 2:
637 // NetworkRead* -> CacheWriteData* -> StartPartialCacheValidation -> 634 // NetworkRead* -> CacheWriteData* -> StartPartialCacheValidation ->
638 // CompletePartialCacheValidation -> CacheReadData* -> 635 // CompletePartialCacheValidation -> CacheReadData* ->
639 // 636 //
640 // Read() 3: 637 // Read() 3:
641 // CacheReadData* -> StartPartialCacheValidation -> 638 // CacheReadData* -> StartPartialCacheValidation ->
(...skipping 20 matching lines...) Expand all
662 // Read(): 659 // Read():
663 // CacheReadData (returns 0) 660 // CacheReadData (returns 0)
664 // 661 //
665 // 9. HEAD. Cached entry, validation and replace (200): 662 // 9. HEAD. Cached entry, validation and replace (200):
666 // Pass through. The request dooms the old entry, as a HEAD won't be stored by 663 // Pass through. The request dooms the old entry, as a HEAD won't be stored by
667 // itself. 664 // itself.
668 // Start(): 665 // Start():
669 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 666 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
670 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 667 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
671 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> 668 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
672 // OverwriteCachedResponse -> FinishHeaders* 669 // OverwriteCachedResponse
673 // 670 //
674 // 10. HEAD. Sparse entry, partially cached: 671 // 10. HEAD. Sparse entry, partially cached:
675 // Serve the request from the cache, as long as it doesn't require 672 // Serve the request from the cache, as long as it doesn't require
676 // revalidation. Ignore missing ranges when deciding to revalidate. If the 673 // revalidation. Ignore missing ranges when deciding to revalidate. If the
677 // entry requires revalidation, ignore the whole request and go to full pass 674 // entry requires revalidation, ignore the whole request and go to full pass
678 // through (the result of the HEAD request will NOT update the entry). 675 // through (the result of the HEAD request will NOT update the entry).
679 // 676 //
680 // Start(): Basically the same as example 7, as we never create a partial_ 677 // Start(): Basically the same as example 7, as we never create a partial_
681 // object for this request. 678 // object for this request.
682 // 679 //
683 // 11. Prefetch, not-cached entry: 680 // 11. Prefetch, not-cached entry:
684 // The same as example 1. The "unused_since_prefetch" bit is stored as true in 681 // The same as example 1. The "unused_since_prefetch" bit is stored as true in
685 // UpdateCachedResponse. 682 // UpdateCachedResponse.
686 // 683 //
687 // 12. Prefetch, cached entry: 684 // 12. Prefetch, cached entry:
688 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between 685 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between
689 // CacheReadResponse* and CacheDispatchValidation if the unused_since_prefetch 686 // CacheReadResponse* and CacheDispatchValidation if the unused_since_prefetch
690 // bit is unset. 687 // bit is unset.
691 // 688 //
692 // 13. Cached entry less than 5 minutes old, unused_since_prefetch is true: 689 // 13. Cached entry less than 5 minutes old, unused_since_prefetch is true:
693 // Skip validation, similar to example 2. 690 // Skip validation, similar to example 2.
694 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 691 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
695 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> 692 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation ->
696 // BeginPartialCacheValidation() -> BeginCacheValidation() -> 693 // BeginPartialCacheValidation() -> BeginCacheValidation() ->
697 // SetupEntryForRead() -> FinishHeaders* 694 // SetupEntryForRead()
698 // 695 //
699 // Read(): 696 // Read():
700 // CacheReadData* 697 // CacheReadData*
701 // 698 //
702 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: 699 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true:
703 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between 700 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between
704 // CacheReadResponse* and CacheDispatchValidation. 701 // CacheReadResponse* and CacheDispatchValidation.
705 int HttpCache::Transaction::DoLoop(int result) { 702 int HttpCache::Transaction::DoLoop(int result) {
706 DCHECK_NE(STATE_UNSET, next_state_); 703 DCHECK_NE(STATE_UNSET, next_state_);
707 DCHECK_NE(STATE_NONE, next_state_); 704 DCHECK_NE(STATE_NONE, next_state_);
708 DCHECK(!in_do_loop_); 705 DCHECK(!in_do_loop_);
709 706
710 int rv = result; 707 int rv = result;
711 State state = next_state_;
712 do { 708 do {
713 state = next_state_; 709 State state = next_state_;
714 next_state_ = STATE_UNSET; 710 next_state_ = STATE_UNSET;
715 base::AutoReset<bool> scoped_in_do_loop(&in_do_loop_, true); 711 base::AutoReset<bool> scoped_in_do_loop(&in_do_loop_, true);
716 712
717 switch (state) { 713 switch (state) {
718 case STATE_GET_BACKEND: 714 case STATE_GET_BACKEND:
719 DCHECK_EQ(OK, rv); 715 DCHECK_EQ(OK, rv);
720 rv = DoGetBackend(); 716 rv = DoGetBackend();
721 break; 717 break;
722 case STATE_GET_BACKEND_COMPLETE: 718 case STATE_GET_BACKEND_COMPLETE:
723 rv = DoGetBackendComplete(rv); 719 rv = DoGetBackendComplete(rv);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 DCHECK_EQ(OK, rv); 836 DCHECK_EQ(OK, rv);
841 rv = DoPartialHeadersReceived(); 837 rv = DoPartialHeadersReceived();
842 break; 838 break;
843 case STATE_CACHE_READ_METADATA: 839 case STATE_CACHE_READ_METADATA:
844 DCHECK_EQ(OK, rv); 840 DCHECK_EQ(OK, rv);
845 rv = DoCacheReadMetadata(); 841 rv = DoCacheReadMetadata();
846 break; 842 break;
847 case STATE_CACHE_READ_METADATA_COMPLETE: 843 case STATE_CACHE_READ_METADATA_COMPLETE:
848 rv = DoCacheReadMetadataComplete(rv); 844 rv = DoCacheReadMetadataComplete(rv);
849 break; 845 break;
850 case STATE_HEADERS_PHASE_CANNOT_PROCEED:
851 rv = DoHeadersPhaseCannotProceed();
852 break;
853 case STATE_FINISH_HEADERS:
854 rv = DoFinishHeaders(rv);
855 break;
856 case STATE_FINISH_HEADERS_COMPLETE:
857 rv = DoFinishHeadersComplete(rv);
858 break;
859 case STATE_NETWORK_READ: 846 case STATE_NETWORK_READ:
860 DCHECK_EQ(OK, rv); 847 DCHECK_EQ(OK, rv);
861 rv = DoNetworkRead(); 848 rv = DoNetworkRead();
862 break; 849 break;
863 case STATE_NETWORK_READ_COMPLETE: 850 case STATE_NETWORK_READ_COMPLETE:
864 rv = DoNetworkReadComplete(rv); 851 rv = DoNetworkReadComplete(rv);
865 break; 852 break;
866 case STATE_CACHE_READ_DATA: 853 case STATE_CACHE_READ_DATA:
867 DCHECK_EQ(OK, rv); 854 DCHECK_EQ(OK, rv);
868 rv = DoCacheReadData(); 855 rv = DoCacheReadData();
(...skipping 16 matching lines...) Expand all
885 break; 872 break;
886 default: 873 default:
887 NOTREACHED() << "bad state " << state; 874 NOTREACHED() << "bad state " << state;
888 rv = ERR_FAILED; 875 rv = ERR_FAILED;
889 break; 876 break;
890 } 877 }
891 DCHECK(next_state_ != STATE_UNSET) << "Previous state was " << state; 878 DCHECK(next_state_ != STATE_UNSET) << "Previous state was " << state;
892 879
893 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 880 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
894 881
895 // Assert Start() state machine's allowed last state in successful cases when
896 // caching is happening.
897 DCHECK(reading_ || rv != OK || !entry_ ||
898 state == STATE_FINISH_HEADERS_COMPLETE);
899
900 if (rv != ERR_IO_PENDING && !callback_.is_null()) { 882 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
901 read_buf_ = nullptr; // Release the buffer before invoking the callback. 883 read_buf_ = NULL; // Release the buffer before invoking the callback.
902 base::ResetAndReturn(&callback_).Run(rv); 884 base::ResetAndReturn(&callback_).Run(rv);
903 } 885 }
904 886
905 return rv; 887 return rv;
906 } 888 }
907 889
908 int HttpCache::Transaction::DoGetBackend() { 890 int HttpCache::Transaction::DoGetBackend() {
909 cache_pending_ = true; 891 cache_pending_ = true;
910 TransitionToState(STATE_GET_BACKEND_COMPLETE); 892 TransitionToState(STATE_GET_BACKEND_COMPLETE);
911 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND); 893 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND);
912 return cache_->GetBackendForTransaction(this); 894 return cache_->GetBackendForTransaction(this);
913 } 895 }
914 896
915 int HttpCache::Transaction::DoGetBackendComplete(int result) { 897 int HttpCache::Transaction::DoGetBackendComplete(int result) {
916 DCHECK(result == OK || result == ERR_FAILED); 898 DCHECK(result == OK || result == ERR_FAILED);
917 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_GET_BACKEND, 899 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_GET_BACKEND,
918 result); 900 result);
919 cache_pending_ = false; 901 cache_pending_ = false;
920 902
921 if (!ShouldPassThrough()) { 903 if (!ShouldPassThrough()) {
922 cache_key_ = cache_->GenerateCacheKey(request_); 904 cache_key_ = cache_->GenerateCacheKey(request_);
923 905
924 // Requested cache access mode. 906 // Requested cache access mode.
925 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { 907 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) {
926 if (effective_load_flags_ & LOAD_BYPASS_CACHE) { 908 if (effective_load_flags_ & LOAD_BYPASS_CACHE) {
927 // The client has asked for nonsense. 909 // The client has asked for nonsense.
928 TransitionToState(STATE_FINISH_HEADERS); 910 TransitionToState(STATE_NONE);
929 return ERR_CACHE_MISS; 911 return ERR_CACHE_MISS;
930 } 912 }
931 mode_ = READ; 913 mode_ = READ;
932 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { 914 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) {
933 mode_ = WRITE; 915 mode_ = WRITE;
934 } else { 916 } else {
935 mode_ = READ_WRITE; 917 mode_ = READ_WRITE;
936 } 918 }
937 919
938 // Downgrade to UPDATE if the request has been externally conditionalized. 920 // Downgrade to UPDATE if the request has been externally conditionalized.
(...skipping 18 matching lines...) Expand all
957 // transaction behaves the same for GET and HEAD requests at this point: if it 939 // transaction behaves the same for GET and HEAD requests at this point: if it
958 // was not modified, the entry is updated and a response is not returned from 940 // was not modified, the entry is updated and a response is not returned from
959 // the cache. If we receive 200, it doesn't matter if there was a validation 941 // the cache. If we receive 200, it doesn't matter if there was a validation
960 // header or not. 942 // header or not.
961 if (request_->method == "HEAD" && mode_ == WRITE) 943 if (request_->method == "HEAD" && mode_ == WRITE)
962 mode_ = NONE; 944 mode_ = NONE;
963 945
964 // If must use cache, then we must fail. This can happen for back/forward 946 // If must use cache, then we must fail. This can happen for back/forward
965 // navigations to a page generated via a form post. 947 // navigations to a page generated via a form post.
966 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { 948 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) {
967 TransitionToState(STATE_FINISH_HEADERS); 949 TransitionToState(STATE_NONE);
968 return ERR_CACHE_MISS; 950 return ERR_CACHE_MISS;
969 } 951 }
970 952
971 if (mode_ == NONE) { 953 if (mode_ == NONE) {
972 if (partial_) { 954 if (partial_) {
973 partial_->RestoreHeaders(&custom_request_->extra_headers); 955 partial_->RestoreHeaders(&custom_request_->extra_headers);
974 partial_.reset(); 956 partial_.reset();
975 } 957 }
976 TransitionToState(STATE_SEND_REQUEST); 958 TransitionToState(STATE_SEND_REQUEST);
977 } else { 959 } else {
978 TransitionToState(STATE_INIT_ENTRY); 960 TransitionToState(STATE_INIT_ENTRY);
979 } 961 }
980 962
981 // This is only set if we have something to do with the response. 963 // This is only set if we have something to do with the response.
982 range_requested_ = (partial_.get() != NULL); 964 range_requested_ = (partial_.get() != NULL);
983 965
984 // mode_ may change later, save the initial mode in case we need to restart
985 // this request.
986 original_mode_ = mode_;
987 return OK; 966 return OK;
988 } 967 }
989 968
990 int HttpCache::Transaction::DoInitEntry() { 969 int HttpCache::Transaction::DoInitEntry() {
991 TRACE_EVENT0("io", "HttpCacheTransaction::DoInitEntry"); 970 TRACE_EVENT0("io", "HttpCacheTransaction::DoInitEntry");
992 DCHECK(!new_entry_); 971 DCHECK(!new_entry_);
993 972
994 if (!cache_.get()) { 973 if (!cache_.get()) {
995 TransitionToState(STATE_FINISH_HEADERS); 974 TransitionToState(STATE_NONE);
996 return ERR_UNEXPECTED; 975 return ERR_UNEXPECTED;
997 } 976 }
998 977
999 if (mode_ == WRITE) { 978 if (mode_ == WRITE) {
1000 TransitionToState(STATE_DOOM_ENTRY); 979 TransitionToState(STATE_DOOM_ENTRY);
1001 return OK; 980 return OK;
1002 } 981 }
1003 982
1004 TransitionToState(STATE_OPEN_ENTRY); 983 TransitionToState(STATE_OPEN_ENTRY);
1005 return OK; 984 return OK;
(...skipping 16 matching lines...) Expand all
1022 // transaction attached. 1001 // transaction attached.
1023 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_OPEN_ENTRY, 1002 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_OPEN_ENTRY,
1024 result); 1003 result);
1025 cache_pending_ = false; 1004 cache_pending_ = false;
1026 if (result == OK) { 1005 if (result == OK) {
1027 TransitionToState(STATE_ADD_TO_ENTRY); 1006 TransitionToState(STATE_ADD_TO_ENTRY);
1028 return OK; 1007 return OK;
1029 } 1008 }
1030 1009
1031 if (result == ERR_CACHE_RACE) { 1010 if (result == ERR_CACHE_RACE) {
1032 TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); 1011 TransitionToState(STATE_INIT_ENTRY);
1033 return OK; 1012 return OK;
1034 } 1013 }
1035 1014
1036 if (request_->method == "PUT" || request_->method == "DELETE" || 1015 if (request_->method == "PUT" || request_->method == "DELETE" ||
1037 (request_->method == "HEAD" && mode_ == READ_WRITE)) { 1016 (request_->method == "HEAD" && mode_ == READ_WRITE)) {
1038 DCHECK(mode_ == READ_WRITE || mode_ == WRITE || request_->method == "HEAD"); 1017 DCHECK(mode_ == READ_WRITE || mode_ == WRITE || request_->method == "HEAD");
1039 mode_ = NONE; 1018 mode_ = NONE;
1040 TransitionToState(STATE_SEND_REQUEST); 1019 TransitionToState(STATE_SEND_REQUEST);
1041 return OK; 1020 return OK;
1042 } 1021 }
1043 1022
1044 if (mode_ == READ_WRITE) { 1023 if (mode_ == READ_WRITE) {
1045 mode_ = WRITE; 1024 mode_ = WRITE;
1046 TransitionToState(STATE_CREATE_ENTRY); 1025 TransitionToState(STATE_CREATE_ENTRY);
1047 return OK; 1026 return OK;
1048 } 1027 }
1049 if (mode_ == UPDATE) { 1028 if (mode_ == UPDATE) {
1050 // There is no cache entry to update; proceed without caching. 1029 // There is no cache entry to update; proceed without caching.
1051 mode_ = NONE; 1030 mode_ = NONE;
1052 TransitionToState(STATE_SEND_REQUEST); 1031 TransitionToState(STATE_SEND_REQUEST);
1053 return OK; 1032 return OK;
1054 } 1033 }
1055 1034
1056 // The entry does not exist, and we are not permitted to create a new entry, 1035 // The entry does not exist, and we are not permitted to create a new entry,
1057 // so we must fail. 1036 // so we must fail.
1058 TransitionToState(STATE_FINISH_HEADERS); 1037 TransitionToState(STATE_NONE);
1059 return ERR_CACHE_MISS; 1038 return ERR_CACHE_MISS;
1060 } 1039 }
1061 1040
1062 int HttpCache::Transaction::DoDoomEntry() { 1041 int HttpCache::Transaction::DoDoomEntry() {
1063 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntry"); 1042 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntry");
1064 TransitionToState(STATE_DOOM_ENTRY_COMPLETE); 1043 TransitionToState(STATE_DOOM_ENTRY_COMPLETE);
1065 cache_pending_ = true; 1044 cache_pending_ = true;
1066 if (first_cache_access_since_.is_null()) 1045 if (first_cache_access_since_.is_null())
1067 first_cache_access_since_ = TimeTicks::Now(); 1046 first_cache_access_since_ = TimeTicks::Now();
1068 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_DOOM_ENTRY); 1047 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_DOOM_ENTRY);
1069 return cache_->DoomEntry(cache_key_, this); 1048 return cache_->DoomEntry(cache_key_, this);
1070 } 1049 }
1071 1050
1072 int HttpCache::Transaction::DoDoomEntryComplete(int result) { 1051 int HttpCache::Transaction::DoDoomEntryComplete(int result) {
1073 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntryComplete"); 1052 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntryComplete");
1074 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_DOOM_ENTRY, 1053 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_DOOM_ENTRY,
1075 result); 1054 result);
1076 cache_pending_ = false; 1055 cache_pending_ = false;
1077 TransitionToState(result == ERR_CACHE_RACE 1056 TransitionToState(result == ERR_CACHE_RACE ? STATE_INIT_ENTRY
1078 ? STATE_HEADERS_PHASE_CANNOT_PROCEED 1057 : STATE_CREATE_ENTRY);
1079 : STATE_CREATE_ENTRY);
1080 return OK; 1058 return OK;
1081 } 1059 }
1082 1060
1083 int HttpCache::Transaction::DoCreateEntry() { 1061 int HttpCache::Transaction::DoCreateEntry() {
1084 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntry"); 1062 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntry");
1085 DCHECK(!new_entry_); 1063 DCHECK(!new_entry_);
1086 TransitionToState(STATE_CREATE_ENTRY_COMPLETE); 1064 TransitionToState(STATE_CREATE_ENTRY_COMPLETE);
1087 cache_pending_ = true; 1065 cache_pending_ = true;
1088 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_CREATE_ENTRY); 1066 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_CREATE_ENTRY);
1089 return cache_->CreateEntry(cache_key_, &new_entry_, this); 1067 return cache_->CreateEntry(cache_key_, &new_entry_, this);
1090 } 1068 }
1091 1069
1092 int HttpCache::Transaction::DoCreateEntryComplete(int result) { 1070 int HttpCache::Transaction::DoCreateEntryComplete(int result) {
1093 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntryComplete"); 1071 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntryComplete");
1094 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is 1072 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is
1095 // OK, otherwise the cache will end up with an active entry without any 1073 // OK, otherwise the cache will end up with an active entry without any
1096 // transaction attached. 1074 // transaction attached.
1097 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_CREATE_ENTRY, 1075 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_CREATE_ENTRY,
1098 result); 1076 result);
1099 cache_pending_ = false; 1077 cache_pending_ = false;
1100 switch (result) { 1078 switch (result) {
1101 case OK: 1079 case OK:
1102 TransitionToState(STATE_ADD_TO_ENTRY); 1080 TransitionToState(STATE_ADD_TO_ENTRY);
1103 break; 1081 break;
1104 1082
1105 case ERR_CACHE_RACE: 1083 case ERR_CACHE_RACE:
1106 TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); 1084 TransitionToState(STATE_INIT_ENTRY);
1107 break; 1085 break;
1108 1086
1109 default: 1087 default:
1110 // We have a race here: Maybe we failed to open the entry and decided to 1088 // We have a race here: Maybe we failed to open the entry and decided to
1111 // create one, but by the time we called create, another transaction 1089 // create one, but by the time we called create, another transaction
1112 // already created the entry. If we want to eliminate this issue, we 1090 // already created the entry. If we want to eliminate this issue, we
1113 // need an atomic OpenOrCreate() method exposed by the disk cache. 1091 // need an atomic OpenOrCreate() method exposed by the disk cache.
1114 DLOG(WARNING) << "Unable to create cache entry"; 1092 DLOG(WARNING) << "Unable to create cache entry";
1115 mode_ = NONE; 1093 mode_ = NONE;
1116 if (partial_) 1094 if (partial_)
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 DCHECK(new_entry_); 1155 DCHECK(new_entry_);
1178 cache_pending_ = false; 1156 cache_pending_ = false;
1179 1157
1180 if (result == OK) 1158 if (result == OK)
1181 entry_ = new_entry_; 1159 entry_ = new_entry_;
1182 1160
1183 // If there is a failure, the cache should have taken care of new_entry_. 1161 // If there is a failure, the cache should have taken care of new_entry_.
1184 new_entry_ = NULL; 1162 new_entry_ = NULL;
1185 1163
1186 if (result == ERR_CACHE_RACE) { 1164 if (result == ERR_CACHE_RACE) {
1187 TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); 1165 TransitionToState(STATE_INIT_ENTRY);
1188 return OK; 1166 return OK;
1189 } 1167 }
1190 1168
1191 if (result == ERR_CACHE_LOCK_TIMEOUT) { 1169 if (result == ERR_CACHE_LOCK_TIMEOUT) {
1192 if (mode_ == READ) { 1170 if (mode_ == READ) {
1193 TransitionToState(STATE_FINISH_HEADERS); 1171 TransitionToState(STATE_NONE);
1194 return ERR_CACHE_MISS; 1172 return ERR_CACHE_MISS;
1195 } 1173 }
1196 1174
1197 // The cache is busy, bypass it for this transaction. 1175 // The cache is busy, bypass it for this transaction.
1198 mode_ = NONE; 1176 mode_ = NONE;
1199 TransitionToState(STATE_SEND_REQUEST); 1177 TransitionToState(STATE_SEND_REQUEST);
1200 if (partial_) { 1178 if (partial_) {
1201 partial_->RestoreHeaders(&custom_request_->extra_headers); 1179 partial_->RestoreHeaders(&custom_request_->extra_headers);
1202 partial_.reset(); 1180 partial_.reset();
1203 } 1181 }
1204 return OK; 1182 return OK;
1205 } 1183 }
1206 1184
1207 // TODO(crbug.com/713354) Access timestamp for histograms only if entry is 1185 open_entry_last_used_ = entry_->disk_entry->GetLastUsed();
1208 // already written, to avoid data race since cache thread can also access
1209 // this.
1210 if (!cache_->IsWritingInProgress(entry_))
1211 open_entry_last_used_ = entry_->disk_entry->GetLastUsed();
1212 1186
1213 // TODO(jkarlin): We should either handle the case or DCHECK. 1187 // TODO(jkarlin): We should either handle the case or DCHECK.
1214 if (result != OK) { 1188 if (result != OK) {
1215 NOTREACHED(); 1189 NOTREACHED();
1216 TransitionToState(STATE_FINISH_HEADERS); 1190 TransitionToState(STATE_NONE);
1217 return result; 1191 return result;
1218 } 1192 }
1219 1193
1220 if (mode_ == WRITE) { 1194 if (mode_ == WRITE) {
1221 if (partial_) 1195 if (partial_)
1222 partial_->RestoreHeaders(&custom_request_->extra_headers); 1196 partial_->RestoreHeaders(&custom_request_->extra_headers);
1223 TransitionToState(STATE_SEND_REQUEST); 1197 TransitionToState(STATE_SEND_REQUEST);
1224 } else { 1198 } else {
1225 // We have to read the headers from the cached entry. 1199 // We have to read the headers from the cached entry.
1226 DCHECK(mode_ & READ_META); 1200 DCHECK(mode_ & READ_META);
(...skipping 18 matching lines...) Expand all
1245 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { 1219 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
1246 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadResponseComplete"); 1220 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadResponseComplete");
1247 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, 1221 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO,
1248 result); 1222 result);
1249 if (result != io_buf_len_ || 1223 if (result != io_buf_len_ ||
1250 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, &response_, 1224 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, &response_,
1251 &truncated_)) { 1225 &truncated_)) {
1252 return OnCacheReadError(result, true); 1226 return OnCacheReadError(result, true);
1253 } 1227 }
1254 1228
1255 // TODO(crbug.com/713354) Only get data size if there is no other transaction 1229 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1256 // currently writing the response body due to the data race mentioned in the 1230 int64_t full_response_length = response_.headers->GetContentLength();
1257 // associated bug.
1258 if (!cache_->IsWritingInProgress(entry_)) {
1259 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1260 int64_t full_response_length = response_.headers->GetContentLength();
1261 1231
1262 // Some resources may have slipped in as truncated when they're not. 1232 // Some resources may have slipped in as truncated when they're not.
1263 if (full_response_length == current_size) 1233 if (full_response_length == current_size)
1264 truncated_ = false; 1234 truncated_ = false;
1265 1235
1266 // The state machine's handling of StopCaching unfortunately doesn't deal 1236 // The state machine's handling of StopCaching unfortunately doesn't deal well
1267 // well with resources that are larger than 2GB when there is a truncated or 1237 // with resources that are larger than 2GB when there is a truncated or sparse
1268 // sparse cache entry. While the state machine is reworked to resolve this, 1238 // cache entry. While the state machine is reworked to resolve this, the
1269 // the following logic is put in place to defer such requests to the 1239 // following logic is put in place to defer such requests to the network. The
1270 // network. The cache should not be storing multi gigabyte resources. See 1240 // cache should not be storing multi gigabyte resources. See
1271 // http://crbug.com/89567. 1241 // http://crbug.com/89567.
1272 if ((truncated_ || response_.headers->response_code() == 206) && 1242 if ((truncated_ || response_.headers->response_code() == 206) &&
1273 !range_requested_ && 1243 !range_requested_ &&
1274 full_response_length > std::numeric_limits<int32_t>::max()) { 1244 full_response_length > std::numeric_limits<int32_t>::max()) {
1275 DCHECK(!partial_); 1245 // Does not release the cache entry. If another transaction wants to use
1276 1246 // this cache entry while this transaction is active, the second transaction
1277 // Doom the entry so that no other transaction gets added to this entry 1247 // will fall back to the network after the timeout.
1278 // and avoid a race of not being able to check this condition because 1248 DCHECK(!partial_);
1279 // writing is in progress. 1249 mode_ = NONE;
1280 cache_->DoneWritingToEntry(entry_, false, this); 1250 TransitionToState(STATE_SEND_REQUEST);
1281 entry_ = nullptr; 1251 return OK;
1282 mode_ = NONE;
1283 TransitionToState(STATE_SEND_REQUEST);
1284 return OK;
1285 }
1286 } 1252 }
1287 1253
1288 if (response_.unused_since_prefetch != 1254 if (response_.unused_since_prefetch !=
1289 !!(request_->load_flags & LOAD_PREFETCH)) { 1255 !!(request_->load_flags & LOAD_PREFETCH)) {
1290 // Either this is the first use of an entry since it was prefetched XOR 1256 // Either this is the first use of an entry since it was prefetched XOR
1291 // this is a prefetch. The value of response.unused_since_prefetch is 1257 // this is a prefetch. The value of response.unused_since_prefetch is
1292 // valid for this transaction but the bit needs to be flipped in storage. 1258 // valid for this transaction but the bit needs to be flipped in storage.
1293 TransitionToState(STATE_TOGGLE_UNUSED_SINCE_PREFETCH); 1259 TransitionToState(STATE_TOGGLE_UNUSED_SINCE_PREFETCH);
1294 return OK; 1260 return OK;
1295 } 1261 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 } 1323 }
1358 1324
1359 int HttpCache::Transaction::DoCacheQueryData() { 1325 int HttpCache::Transaction::DoCacheQueryData() {
1360 TransitionToState(STATE_CACHE_QUERY_DATA_COMPLETE); 1326 TransitionToState(STATE_CACHE_QUERY_DATA_COMPLETE);
1361 return entry_->disk_entry->ReadyForSparseIO(io_callback_); 1327 return entry_->disk_entry->ReadyForSparseIO(io_callback_);
1362 } 1328 }
1363 1329
1364 int HttpCache::Transaction::DoCacheQueryDataComplete(int result) { 1330 int HttpCache::Transaction::DoCacheQueryDataComplete(int result) {
1365 DCHECK_EQ(OK, result); 1331 DCHECK_EQ(OK, result);
1366 if (!cache_.get()) { 1332 if (!cache_.get()) {
1367 TransitionToState(STATE_FINISH_HEADERS); 1333 TransitionToState(STATE_NONE);
1368 return ERR_UNEXPECTED; 1334 return ERR_UNEXPECTED;
1369 } 1335 }
1370 1336
1371 return ValidateEntryHeadersAndContinue(); 1337 return ValidateEntryHeadersAndContinue();
1372 } 1338 }
1373 1339
1374 // We may end up here multiple times for a given request. 1340 // We may end up here multiple times for a given request.
1375 int HttpCache::Transaction::DoStartPartialCacheValidation() { 1341 int HttpCache::Transaction::DoStartPartialCacheValidation() {
1376 if (mode_ == NONE) { 1342 if (mode_ == NONE) {
1377 TransitionToState(STATE_FINISH_HEADERS); 1343 TransitionToState(STATE_NONE);
1378 return OK; 1344 return OK;
1379 } 1345 }
1380 1346
1381 TransitionToState(STATE_COMPLETE_PARTIAL_CACHE_VALIDATION); 1347 TransitionToState(STATE_COMPLETE_PARTIAL_CACHE_VALIDATION);
1382 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); 1348 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_);
1383 } 1349 }
1384 1350
1385 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { 1351 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) {
1386 if (!result) { 1352 if (!result) {
1387 // This is the end of the request. 1353 // This is the end of the request.
1388 if (mode_ & WRITE) { 1354 if (mode_ & WRITE) {
1389 DoneWritingToEntry(true); 1355 DoneWritingToEntry(true);
1390 } else { 1356 } else {
1391 cache_->DoneReadingFromEntry(entry_, this); 1357 cache_->DoneReadingFromEntry(entry_, this);
1392 entry_ = NULL; 1358 entry_ = NULL;
1393 } 1359 }
1394 TransitionToState(STATE_FINISH_HEADERS); 1360 TransitionToState(STATE_NONE);
1395 return result; 1361 return result;
1396 } 1362 }
1397 1363
1398 if (result < 0) { 1364 if (result < 0) {
1399 TransitionToState(STATE_FINISH_HEADERS); 1365 TransitionToState(STATE_NONE);
1400 return result; 1366 return result;
1401 } 1367 }
1402 1368
1403 partial_->PrepareCacheValidation(entry_->disk_entry, 1369 partial_->PrepareCacheValidation(entry_->disk_entry,
1404 &custom_request_->extra_headers); 1370 &custom_request_->extra_headers);
1405 1371
1406 if (reading_ && partial_->IsCurrentRangeCached()) { 1372 if (reading_ && partial_->IsCurrentRangeCached()) {
1407 TransitionToState(STATE_CACHE_READ_DATA); 1373 TransitionToState(STATE_CACHE_READ_DATA);
1408 return OK; 1374 return OK;
1409 } 1375 }
1410 1376
1411 return BeginCacheValidation(); 1377 return BeginCacheValidation();
1412 } 1378 }
1413 1379
1414 int HttpCache::Transaction::DoSendRequest() { 1380 int HttpCache::Transaction::DoSendRequest() {
1415 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequest"); 1381 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequest");
1416 DCHECK(mode_ & WRITE || mode_ == NONE); 1382 DCHECK(mode_ & WRITE || mode_ == NONE);
1417 DCHECK(!network_trans_.get()); 1383 DCHECK(!network_trans_.get());
1418 1384
1419 send_request_since_ = TimeTicks::Now(); 1385 send_request_since_ = TimeTicks::Now();
1420 1386
1421 // Create a network transaction. 1387 // Create a network transaction.
1422 int rv = 1388 int rv =
1423 cache_->network_layer_->CreateTransaction(priority_, &network_trans_); 1389 cache_->network_layer_->CreateTransaction(priority_, &network_trans_);
1424 if (rv != OK) { 1390 if (rv != OK) {
1425 TransitionToState(STATE_FINISH_HEADERS); 1391 TransitionToState(STATE_NONE);
1426 return rv; 1392 return rv;
1427 } 1393 }
1428 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_); 1394 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_);
1429 network_trans_->SetBeforeHeadersSentCallback(before_headers_sent_callback_); 1395 network_trans_->SetBeforeHeadersSentCallback(before_headers_sent_callback_);
1430 1396
1431 // Old load timing information, if any, is now obsolete. 1397 // Old load timing information, if any, is now obsolete.
1432 old_network_trans_load_timing_.reset(); 1398 old_network_trans_load_timing_.reset();
1433 old_remote_endpoint_ = IPEndPoint(); 1399 old_remote_endpoint_ = IPEndPoint();
1434 1400
1435 if (websocket_handshake_stream_base_create_helper_) 1401 if (websocket_handshake_stream_base_create_helper_)
1436 network_trans_->SetWebSocketHandshakeStreamCreateHelper( 1402 network_trans_->SetWebSocketHandshakeStreamCreateHelper(
1437 websocket_handshake_stream_base_create_helper_); 1403 websocket_handshake_stream_base_create_helper_);
1438 1404
1439 TransitionToState(STATE_SEND_REQUEST_COMPLETE); 1405 TransitionToState(STATE_SEND_REQUEST_COMPLETE);
1440 rv = network_trans_->Start(request_, io_callback_, net_log_); 1406 rv = network_trans_->Start(request_, io_callback_, net_log_);
1441 return rv; 1407 return rv;
1442 } 1408 }
1443 1409
1444 int HttpCache::Transaction::DoSendRequestComplete(int result) { 1410 int HttpCache::Transaction::DoSendRequestComplete(int result) {
1445 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequestComplete"); 1411 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequestComplete");
1446 if (!cache_.get()) { 1412 if (!cache_.get()) {
1447 TransitionToState(STATE_FINISH_HEADERS); 1413 TransitionToState(STATE_NONE);
1448 return ERR_UNEXPECTED; 1414 return ERR_UNEXPECTED;
1449 } 1415 }
1450 1416
1451 // If we tried to conditionalize the request and failed, we know 1417 // If we tried to conditionalize the request and failed, we know
1452 // we won't be reading from the cache after this point. 1418 // we won't be reading from the cache after this point.
1453 if (couldnt_conditionalize_request_) 1419 if (couldnt_conditionalize_request_)
1454 mode_ = WRITE; 1420 mode_ = WRITE;
1455 1421
1456 if (result == OK) { 1422 if (result == OK) {
1457 TransitionToState(STATE_SUCCESSFUL_SEND_REQUEST); 1423 TransitionToState(STATE_SUCCESSFUL_SEND_REQUEST);
(...skipping 10 matching lines...) Expand all
1468 // so GetResponseInfo() should never return NULL here. 1434 // so GetResponseInfo() should never return NULL here.
1469 DCHECK(response); 1435 DCHECK(response);
1470 response_.ssl_info = response->ssl_info; 1436 response_.ssl_info = response->ssl_info;
1471 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 1437 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
1472 DCHECK(response); 1438 DCHECK(response);
1473 response_.cert_request_info = response->cert_request_info; 1439 response_.cert_request_info = response->cert_request_info;
1474 } else if (response_.was_cached) { 1440 } else if (response_.was_cached) {
1475 DoneWritingToEntry(true); 1441 DoneWritingToEntry(true);
1476 } 1442 }
1477 1443
1478 TransitionToState(STATE_FINISH_HEADERS); 1444 TransitionToState(STATE_NONE);
1479 return result; 1445 return result;
1480 } 1446 }
1481 1447
1482 // We received the response headers and there is no error. 1448 // We received the response headers and there is no error.
1483 int HttpCache::Transaction::DoSuccessfulSendRequest() { 1449 int HttpCache::Transaction::DoSuccessfulSendRequest() {
1484 TRACE_EVENT0("io", "HttpCacheTransaction::DoSuccessfulSendRequest"); 1450 TRACE_EVENT0("io", "HttpCacheTransaction::DoSuccessfulSendRequest");
1485 DCHECK(!new_response_); 1451 DCHECK(!new_response_);
1486 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); 1452 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo();
1487 1453
1488 if (new_response->headers->response_code() == 401 || 1454 if (new_response->headers->response_code() == 401 ||
1489 new_response->headers->response_code() == 407) { 1455 new_response->headers->response_code() == 407) {
1490 SetAuthResponse(*new_response); 1456 SetAuthResponse(*new_response);
1491 if (!reading_) { 1457 if (!reading_) {
1492 TransitionToState(STATE_FINISH_HEADERS); 1458 TransitionToState(STATE_NONE);
1493 return OK; 1459 return OK;
1494 } 1460 }
1495 1461
1496 // We initiated a second request the caller doesn't know about. We should be 1462 // We initiated a second request the caller doesn't know about. We should be
1497 // able to authenticate this request because we should have authenticated 1463 // able to authenticate this request because we should have authenticated
1498 // this URL moments ago. 1464 // this URL moments ago.
1499 if (IsReadyToRestartForAuth()) { 1465 if (IsReadyToRestartForAuth()) {
1500 DCHECK(!response_.auth_challenge.get()); 1466 DCHECK(!response_.auth_challenge.get());
1501 TransitionToState(STATE_SEND_REQUEST_COMPLETE); 1467 TransitionToState(STATE_SEND_REQUEST_COMPLETE);
1502 // In theory we should check to see if there are new cookies, but there 1468 // In theory we should check to see if there are new cookies, but there
1503 // is no way to do that from here. 1469 // is no way to do that from here.
1504 return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_); 1470 return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_);
1505 } 1471 }
1506 1472
1507 // We have to perform cleanup at this point so that at least the next 1473 // We have to perform cleanup at this point so that at least the next
1508 // request can succeed. We do not retry at this point, because data 1474 // request can succeed. We do not retry at this point, because data
1509 // has been read and we have no way to gather credentials. We would 1475 // has been read and we have no way to gather credentials. We would
1510 // fail again, and potentially loop. This can happen if the credentials 1476 // fail again, and potentially loop. This can happen if the credentials
1511 // expire while chrome is suspended. 1477 // expire while chrome is suspended.
1512 if (entry_) 1478 if (entry_)
1513 DoomPartialEntry(false); 1479 DoomPartialEntry(false);
1514 mode_ = NONE; 1480 mode_ = NONE;
1515 partial_.reset(); 1481 partial_.reset();
1516 ResetNetworkTransaction(); 1482 ResetNetworkTransaction();
1517 TransitionToState(STATE_FINISH_HEADERS); 1483 TransitionToState(STATE_NONE);
1518 return ERR_CACHE_AUTH_FAILURE_AFTER_READ; 1484 return ERR_CACHE_AUTH_FAILURE_AFTER_READ;
1519 } 1485 }
1520 1486
1521 new_response_ = new_response; 1487 new_response_ = new_response;
1522 if (!ValidatePartialResponse() && !auth_response_.headers.get()) { 1488 if (!ValidatePartialResponse() && !auth_response_.headers.get()) {
1523 // Something went wrong with this request and we have to restart it. 1489 // Something went wrong with this request and we have to restart it.
1524 // If we have an authentication response, we are exposed to weird things 1490 // If we have an authentication response, we are exposed to weird things
1525 // hapenning if the user cancels the authentication before we receive 1491 // hapenning if the user cancels the authentication before we receive
1526 // the new response. 1492 // the new response.
1527 net_log_.AddEvent(NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); 1493 net_log_.AddEvent(NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST);
(...skipping 17 matching lines...) Expand all
1545 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_NOT_IN_CACHE); 1511 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_NOT_IN_CACHE);
1546 } 1512 }
1547 1513
1548 // Invalidate any cached GET with a successful PUT or DELETE. 1514 // Invalidate any cached GET with a successful PUT or DELETE.
1549 if (mode_ == WRITE && 1515 if (mode_ == WRITE &&
1550 (request_->method == "PUT" || request_->method == "DELETE")) { 1516 (request_->method == "PUT" || request_->method == "DELETE")) {
1551 if (NonErrorResponse(new_response->headers->response_code())) { 1517 if (NonErrorResponse(new_response->headers->response_code())) {
1552 int ret = cache_->DoomEntry(cache_key_, NULL); 1518 int ret = cache_->DoomEntry(cache_key_, NULL);
1553 DCHECK_EQ(OK, ret); 1519 DCHECK_EQ(OK, ret);
1554 } 1520 }
1555 cache_->DoneWritingToEntry(entry_, true, this); 1521 cache_->DoneWritingToEntry(entry_, true);
1556 entry_ = NULL; 1522 entry_ = NULL;
1557 mode_ = NONE; 1523 mode_ = NONE;
1558 } 1524 }
1559 1525
1560 // Invalidate any cached GET with a successful POST. 1526 // Invalidate any cached GET with a successful POST.
1561 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && 1527 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) &&
1562 request_->method == "POST" && 1528 request_->method == "POST" &&
1563 NonErrorResponse(new_response->headers->response_code())) { 1529 NonErrorResponse(new_response->headers->response_code())) {
1564 cache_->DoomMainEntryForUrl(request_->url); 1530 cache_->DoomMainEntryForUrl(request_->url);
1565 } 1531 }
1566 1532
1567 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); 1533 RecordNoStoreHeaderHistogram(request_->load_flags, new_response);
1568 1534
1569 if (new_response_->headers->response_code() == 416 && 1535 if (new_response_->headers->response_code() == 416 &&
1570 (request_->method == "GET" || request_->method == "POST")) { 1536 (request_->method == "GET" || request_->method == "POST")) {
1571 // If there is an active entry it may be destroyed with this transaction. 1537 // If there is an active entry it may be destroyed with this transaction.
1572 SetResponse(*new_response_); 1538 SetResponse(*new_response_);
1573 TransitionToState(STATE_FINISH_HEADERS); 1539 TransitionToState(STATE_NONE);
1574 return OK; 1540 return OK;
1575 } 1541 }
1576 1542
1577 // Are we expecting a response to a conditional query? 1543 // Are we expecting a response to a conditional query?
1578 if (mode_ == READ_WRITE || mode_ == UPDATE) { 1544 if (mode_ == READ_WRITE || mode_ == UPDATE) {
1579 if (new_response->headers->response_code() == 304 || handling_206_) { 1545 if (new_response->headers->response_code() == 304 || handling_206_) {
1580 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); 1546 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED);
1581 TransitionToState(STATE_UPDATE_CACHED_RESPONSE); 1547 TransitionToState(STATE_UPDATE_CACHED_RESPONSE);
1582 return OK; 1548 return OK;
1583 } 1549 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 DCHECK(!handling_206_); 1617 DCHECK(!handling_206_);
1652 // We got a "not modified" response and already updated the corresponding 1618 // We got a "not modified" response and already updated the corresponding
1653 // cache entry above. 1619 // cache entry above.
1654 // 1620 //
1655 // By closing the cached entry now, we make sure that the 304 rather than 1621 // By closing the cached entry now, we make sure that the 304 rather than
1656 // the cached 200 response, is what will be returned to the user. 1622 // the cached 200 response, is what will be returned to the user.
1657 DoneWritingToEntry(true); 1623 DoneWritingToEntry(true);
1658 } else if (entry_ && !handling_206_) { 1624 } else if (entry_ && !handling_206_) {
1659 DCHECK_EQ(READ_WRITE, mode_); 1625 DCHECK_EQ(READ_WRITE, mode_);
1660 if (!partial_ || partial_->IsLastRange()) { 1626 if (!partial_ || partial_->IsLastRange()) {
1627 cache_->ConvertWriterToReader(entry_);
1661 mode_ = READ; 1628 mode_ = READ;
1662 } 1629 }
1663 // We no longer need the network transaction, so destroy it. 1630 // We no longer need the network transaction, so destroy it.
1664 ResetNetworkTransaction(); 1631 ResetNetworkTransaction();
1665 } else if (entry_ && handling_206_ && truncated_ && 1632 } else if (entry_ && handling_206_ && truncated_ &&
1666 partial_->initial_validation()) { 1633 partial_->initial_validation()) {
1667 // We just finished the validation of a truncated entry, and the server 1634 // We just finished the validation of a truncated entry, and the server
1668 // is willing to resume the operation. Now we go back and start serving 1635 // is willing to resume the operation. Now we go back and start serving
1669 // the first part to the user. 1636 // the first part to the user.
1670 ResetNetworkTransaction(); 1637 ResetNetworkTransaction();
(...skipping 17 matching lines...) Expand all
1688 if (handling_206_ && partial_) 1655 if (handling_206_ && partial_)
1689 partial_->FixContentLength(new_response_->headers.get()); 1656 partial_->FixContentLength(new_response_->headers.get());
1690 1657
1691 SetResponse(*new_response_); 1658 SetResponse(*new_response_);
1692 1659
1693 if (request_->method == "HEAD") { 1660 if (request_->method == "HEAD") {
1694 // This response is replacing the cached one. 1661 // This response is replacing the cached one.
1695 DoneWritingToEntry(false); 1662 DoneWritingToEntry(false);
1696 mode_ = NONE; 1663 mode_ = NONE;
1697 new_response_ = NULL; 1664 new_response_ = NULL;
1698 TransitionToState(STATE_FINISH_HEADERS); 1665 TransitionToState(STATE_NONE);
1699 return OK; 1666 return OK;
1700 } 1667 }
1701 1668
1702 if (handling_206_ && !CanResume(false)) { 1669 if (handling_206_ && !CanResume(false)) {
1703 // There is no point in storing this resource because it will never be used. 1670 // There is no point in storing this resource because it will never be used.
1704 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. 1671 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries.
1705 DoneWritingToEntry(false); 1672 DoneWritingToEntry(false);
1706 if (partial_) 1673 if (partial_)
1707 partial_->FixResponseHeaders(response_.headers.get(), true); 1674 partial_->FixResponseHeaders(response_.headers.get(), true);
1708 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); 1675 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED);
1709 return OK; 1676 return OK;
1710 } 1677 }
1711 1678
1712 TransitionToState(STATE_CACHE_WRITE_RESPONSE); 1679 TransitionToState(STATE_CACHE_WRITE_RESPONSE);
1713 return OK; 1680 return OK;
1714 } 1681 }
1715 1682
1716 int HttpCache::Transaction::DoCacheWriteResponse() { 1683 int HttpCache::Transaction::DoCacheWriteResponse() {
1717 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); 1684 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse");
1718 TransitionToState(STATE_CACHE_WRITE_RESPONSE_COMPLETE); 1685 TransitionToState(STATE_CACHE_WRITE_RESPONSE_COMPLETE);
1719
1720 // Invalidate any current entry with a successful response if this transaction
1721 // cannot write to this entry. This transaction then continues to read from
1722 // the network without writing to the backend.
1723 bool is_match = response_.headers->response_code() == 304;
1724 if (entry_ && response_.headers &&
1725 !cache_->CanTransactionWriteResponseHeaders(entry_, this, is_match)) {
1726 cache_->DoneWritingToEntry(entry_, false, this);
1727 entry_ = nullptr;
1728 mode_ = NONE;
1729 return OK;
1730 }
1731
1732 return WriteResponseInfoToEntry(truncated_); 1686 return WriteResponseInfoToEntry(truncated_);
1733 } 1687 }
1734 1688
1735 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { 1689 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) {
1736 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); 1690 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete");
1737 TransitionToState(STATE_TRUNCATE_CACHED_DATA); 1691 TransitionToState(STATE_TRUNCATE_CACHED_DATA);
1738 return OnWriteResponseInfoToEntryComplete(result); 1692 return OnWriteResponseInfoToEntryComplete(result);
1739 } 1693 }
1740 1694
1741 int HttpCache::Transaction::DoTruncateCachedData() { 1695 int HttpCache::Transaction::DoTruncateCachedData() {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1783 } 1737 }
1784 1738
1785 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); 1739 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED);
1786 return OK; 1740 return OK;
1787 } 1741 }
1788 1742
1789 int HttpCache::Transaction::DoPartialHeadersReceived() { 1743 int HttpCache::Transaction::DoPartialHeadersReceived() {
1790 new_response_ = NULL; 1744 new_response_ = NULL;
1791 1745
1792 if (!partial_) { 1746 if (!partial_) {
1793 if (entry_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) { 1747 if (entry_ && entry_->disk_entry->GetDataSize(kMetadataIndex))
1794 TransitionToState(STATE_CACHE_READ_METADATA); 1748 TransitionToState(STATE_CACHE_READ_METADATA);
1795 } else { 1749 else
1796 DCHECK(!reading_); 1750 TransitionToState(STATE_NONE);
1797 TransitionToState(STATE_FINISH_HEADERS);
1798 }
1799 return OK; 1751 return OK;
1800 } 1752 }
1801 1753
1802 if (reading_) { 1754 if (reading_) {
1803 if (network_trans_.get()) { 1755 if (network_trans_.get()) {
1804 TransitionToState(STATE_NETWORK_READ); 1756 TransitionToState(STATE_NETWORK_READ);
1805 } else { 1757 } else {
1806 TransitionToState(STATE_CACHE_READ_DATA); 1758 TransitionToState(STATE_CACHE_READ_DATA);
1807 } 1759 }
1808 } else if (mode_ != NONE) { 1760 } else if (mode_ != NONE) {
1809 // We are about to return the headers for a byte-range request to the user, 1761 // We are about to return the headers for a byte-range request to the user,
1810 // so let's fix them. 1762 // so let's fix them.
1811 partial_->FixResponseHeaders(response_.headers.get(), true); 1763 partial_->FixResponseHeaders(response_.headers.get(), true);
1812 TransitionToState(STATE_FINISH_HEADERS); 1764 TransitionToState(STATE_NONE);
1813 } else { 1765 } else {
1814 TransitionToState(STATE_FINISH_HEADERS); 1766 TransitionToState(STATE_NONE);
1815 } 1767 }
1816 return OK; 1768 return OK;
1817 } 1769 }
1818 1770
1819 int HttpCache::Transaction::DoHeadersPhaseCannotProceed() {
1820 // If its the Start state machine and it cannot proceed due to a cache
1821 // failure, restart this transaction.
1822 DCHECK(!reading_);
1823 TransitionToState(STATE_INIT_ENTRY);
1824 cache_entry_status_ = CacheEntryStatus::ENTRY_UNDEFINED;
1825 entry_ = nullptr;
1826 mode_ = original_mode_;
1827 if (network_trans_)
1828 network_trans_.reset();
1829 return OK;
1830 }
1831
1832 int HttpCache::Transaction::DoFinishHeaders(int result) {
1833 if (!entry_ || result != OK) {
1834 TransitionToState(STATE_NONE);
1835 return result;
1836 }
1837
1838 TransitionToState(STATE_FINISH_HEADERS_COMPLETE);
1839
1840 // If it was an auth failure or 416, this transaction should continue to be
1841 // headers_transaction till consumer takes an action, so no need to do
1842 // anything now.
1843 if (auth_response_.headers.get() ||
1844 (new_response_ && new_response_->headers &&
1845 new_response_->headers->response_code() == 416))
1846 return OK;
1847
1848 // If there is no response body to be written or read, it does not need to
1849 // wait.
1850 if (request_->method == "HEAD")
1851 return OK;
1852
1853 // If the transaction needs to wait because another transaction is still
1854 // writing the response body, it will return ERR_IO_PENDING now and the
1855 // io_callback_ will be invoked when the wait is done.
1856 return cache_->DoneWithResponseHeaders(entry_, this);
1857 }
1858
1859 int HttpCache::Transaction::DoFinishHeadersComplete(int rv) {
1860 if (rv == ERR_CACHE_RACE) {
1861 TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED);
1862 return OK;
1863 }
1864
1865 TransitionToState(STATE_NONE);
1866 return rv;
1867 }
1868
1869 int HttpCache::Transaction::DoCacheReadMetadata() { 1771 int HttpCache::Transaction::DoCacheReadMetadata() {
1870 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata"); 1772 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata");
1871 DCHECK(entry_); 1773 DCHECK(entry_);
1872 DCHECK(!response_.metadata.get()); 1774 DCHECK(!response_.metadata.get());
1873 TransitionToState(STATE_CACHE_READ_METADATA_COMPLETE); 1775 TransitionToState(STATE_CACHE_READ_METADATA_COMPLETE);
1874 1776
1875 response_.metadata = 1777 response_.metadata =
1876 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); 1778 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex));
1877 1779
1878 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO); 1780 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO);
1879 return entry_->disk_entry->ReadData(kMetadataIndex, 0, 1781 return entry_->disk_entry->ReadData(kMetadataIndex, 0,
1880 response_.metadata.get(), 1782 response_.metadata.get(),
1881 response_.metadata->size(), 1783 response_.metadata->size(),
1882 io_callback_); 1784 io_callback_);
1883 } 1785 }
1884 1786
1885 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { 1787 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) {
1886 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadataComplete"); 1788 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadataComplete");
1887 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, 1789 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO,
1888 result); 1790 result);
1889 if (result != response_.metadata->size()) 1791 if (result != response_.metadata->size())
1890 return OnCacheReadError(result, false); 1792 return OnCacheReadError(result, false);
1891 1793 TransitionToState(STATE_NONE);
1892 TransitionToState(STATE_FINISH_HEADERS);
1893 return OK; 1794 return OK;
1894 } 1795 }
1895 1796
1896 int HttpCache::Transaction::DoNetworkRead() { 1797 int HttpCache::Transaction::DoNetworkRead() {
1897 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); 1798 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead");
1898 TransitionToState(STATE_NETWORK_READ_COMPLETE); 1799 TransitionToState(STATE_NETWORK_READ_COMPLETE);
1899 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); 1800 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_);
1900 } 1801 }
1901 1802
1902 int HttpCache::Transaction::DoNetworkReadComplete(int result) { 1803 int HttpCache::Transaction::DoNetworkReadComplete(int result) {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
2179 return false; 2080 return false;
2180 2081
2181 return true; 2082 return true;
2182 } 2083 }
2183 2084
2184 int HttpCache::Transaction::BeginCacheRead() { 2085 int HttpCache::Transaction::BeginCacheRead() {
2185 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. 2086 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges.
2186 // TODO(jkarlin): Either handle this case or DCHECK. 2087 // TODO(jkarlin): Either handle this case or DCHECK.
2187 if (response_.headers->response_code() == 206 || partial_) { 2088 if (response_.headers->response_code() == 206 || partial_) {
2188 NOTREACHED(); 2089 NOTREACHED();
2189 TransitionToState(STATE_FINISH_HEADERS); 2090 TransitionToState(STATE_NONE);
2190 return ERR_CACHE_MISS; 2091 return ERR_CACHE_MISS;
2191 } 2092 }
2192 2093
2193 // We don't have the whole resource. 2094 // We don't have the whole resource.
2194 if (truncated_) { 2095 if (truncated_) {
2195 TransitionToState(STATE_FINISH_HEADERS); 2096 TransitionToState(STATE_NONE);
2196 return ERR_CACHE_MISS; 2097 return ERR_CACHE_MISS;
2197 } 2098 }
2198 2099
2199 if (RequiresValidation()) { 2100 if (RequiresValidation()) {
2200 TransitionToState(STATE_FINISH_HEADERS); 2101 TransitionToState(STATE_NONE);
2201 return ERR_CACHE_MISS; 2102 return ERR_CACHE_MISS;
2202 } 2103 }
2203 2104
2204 if (request_->method == "HEAD") 2105 if (request_->method == "HEAD")
2205 FixHeadersForHead(); 2106 FixHeadersForHead();
2206 2107
2207 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) 2108 if (entry_->disk_entry->GetDataSize(kMetadataIndex))
2208 TransitionToState(STATE_CACHE_READ_METADATA); 2109 TransitionToState(STATE_CACHE_READ_METADATA);
2209 else 2110 else
2210 TransitionToState(STATE_FINISH_HEADERS); 2111 TransitionToState(STATE_NONE);
2211 2112
2212 return OK; 2113 return OK;
2213 } 2114 }
2214 2115
2215 int HttpCache::Transaction::BeginCacheValidation() { 2116 int HttpCache::Transaction::BeginCacheValidation() {
2216 DCHECK_EQ(mode_, READ_WRITE); 2117 DCHECK_EQ(mode_, READ_WRITE);
2217 2118
2218 bool skip_validation = !RequiresValidation(); 2119 bool skip_validation = !RequiresValidation();
2219 2120
2220 if (request_->method == "HEAD" && 2121 if (request_->method == "HEAD" &&
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
2660 if (partial_) { 2561 if (partial_) {
2661 if (truncated_ || is_sparse_ || !invalid_range_) { 2562 if (truncated_ || is_sparse_ || !invalid_range_) {
2662 // We are going to return the saved response headers to the caller, so 2563 // We are going to return the saved response headers to the caller, so
2663 // we may need to adjust them first. 2564 // we may need to adjust them first.
2664 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); 2565 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED);
2665 return OK; 2566 return OK;
2666 } else { 2567 } else {
2667 partial_.reset(); 2568 partial_.reset();
2668 } 2569 }
2669 } 2570 }
2670 2571 cache_->ConvertWriterToReader(entry_);
2671 mode_ = READ; 2572 mode_ = READ;
2672 2573
2673 if (request_->method == "HEAD") 2574 if (request_->method == "HEAD")
2674 FixHeadersForHead(); 2575 FixHeadersForHead();
2675 2576
2676 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) 2577 if (entry_->disk_entry->GetDataSize(kMetadataIndex))
2677 TransitionToState(STATE_CACHE_READ_METADATA); 2578 TransitionToState(STATE_CACHE_READ_METADATA);
2678 else 2579 else
2679 TransitionToState(STATE_FINISH_HEADERS); 2580 TransitionToState(STATE_NONE);
2680 return OK; 2581 return OK;
2681 } 2582 }
2682 2583
2683 int HttpCache::Transaction::WriteToEntry(int index, int offset, 2584 int HttpCache::Transaction::WriteToEntry(int index, int offset,
2684 IOBuffer* data, int data_len, 2585 IOBuffer* data, int data_len,
2685 const CompletionCallback& callback) { 2586 const CompletionCallback& callback) {
2686 if (!entry_) 2587 if (!entry_)
2687 return data_len; 2588 return data_len;
2688 2589
2689 int rv = 0; 2590 int rv = 0;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2748 } 2649 }
2749 return OK; 2650 return OK;
2750 } 2651 }
2751 2652
2752 void HttpCache::Transaction::DoneWritingToEntry(bool success) { 2653 void HttpCache::Transaction::DoneWritingToEntry(bool success) {
2753 if (!entry_) 2654 if (!entry_)
2754 return; 2655 return;
2755 2656
2756 RecordHistograms(); 2657 RecordHistograms();
2757 2658
2758 cache_->DoneWritingToEntry(entry_, success, this); 2659 cache_->DoneWritingToEntry(entry_, success);
2759 entry_ = NULL; 2660 entry_ = NULL;
2760 mode_ = NONE; // switch to 'pass through' mode 2661 mode_ = NONE; // switch to 'pass through' mode
2761 } 2662 }
2762 2663
2763 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { 2664 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) {
2764 DLOG(ERROR) << "ReadData failed: " << result; 2665 DLOG(ERROR) << "ReadData failed: " << result;
2765 const int result_for_histogram = std::max(0, -result); 2666 const int result_for_histogram = std::max(0, -result);
2766 if (restart) { 2667 if (restart) {
2767 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", 2668 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable",
2768 result_for_histogram); 2669 result_for_histogram);
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2959 bool validation_request = 2860 bool validation_request =
2960 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || 2861 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED ||
2961 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED; 2862 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED;
2962 2863
2963 bool stale_request = 2864 bool stale_request =
2964 validation_cause_ == VALIDATION_CAUSE_STALE && 2865 validation_cause_ == VALIDATION_CAUSE_STALE &&
2965 (validation_request || 2866 (validation_request ||
2966 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); 2867 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE);
2967 int64_t freshness_periods_since_last_used = 0; 2868 int64_t freshness_periods_since_last_used = 0;
2968 2869
2969 if (stale_request && !open_entry_last_used_.is_null()) { 2870 if (stale_request) {
2970 // Note that we are not able to capture those transactions' histograms which
2971 // when added to entry, the response was being written by another
2972 // transaction because getting the last used timestamp might lead to a data
2973 // race in that case. TODO(crbug.com/713354).
2974
2975 // For stale entries, record how many freshness periods have elapsed since 2871 // For stale entries, record how many freshness periods have elapsed since
2976 // the entry was last used. 2872 // the entry was last used.
2873 DCHECK(!open_entry_last_used_.is_null());
2977 DCHECK(!stale_entry_freshness_.is_zero()); 2874 DCHECK(!stale_entry_freshness_.is_zero());
2978 base::TimeDelta time_since_use = base::Time::Now() - open_entry_last_used_; 2875 base::TimeDelta time_since_use = base::Time::Now() - open_entry_last_used_;
2979 freshness_periods_since_last_used = 2876 freshness_periods_since_last_used =
2980 (time_since_use * 1000) / stale_entry_freshness_; 2877 (time_since_use * 1000) / stale_entry_freshness_;
2981 2878
2982 if (validation_request) { 2879 if (validation_request) {
2983 int64_t age_in_freshness_periods = 2880 int64_t age_in_freshness_periods =
2984 (stale_entry_age_ * 100) / stale_entry_freshness_; 2881 (stale_entry_age_ * 100) / stale_entry_freshness_;
2985 if (cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED) { 2882 if (cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED) {
2986 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Validated.Age", 2883 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Validated.Age",
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
3120 } 3017 }
3121 3018
3122 void HttpCache::Transaction::TransitionToState(State state) { 3019 void HttpCache::Transaction::TransitionToState(State state) {
3123 // Ensure that the state is only set once per Do* state. 3020 // Ensure that the state is only set once per Do* state.
3124 DCHECK(in_do_loop_); 3021 DCHECK(in_do_loop_);
3125 DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state; 3022 DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state;
3126 next_state_ = state; 3023 next_state_ = state;
3127 } 3024 }
3128 3025
3129 } // namespace net 3026 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | net/http/http_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698