OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_cache_transaction.h" | 5 #include "net/http/http_cache_transaction.h" |
6 | 6 |
7 #include "build/build_config.h" // For OS_POSIX | 7 #include "build/build_config.h" // For OS_POSIX |
8 | 8 |
9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |