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

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

Issue 2767033003: [HttpCache::Transaction] Ensure each state only sets the next state once (Closed)
Patch Set: AutoReset Created 3 years, 9 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') | no next file » | 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>
11 #endif 11 #endif
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <string> 14 #include <string>
15 15
16 #include "base/auto_reset.h"
16 #include "base/bind.h" 17 #include "base/bind.h"
17 #include "base/callback_helpers.h" 18 #include "base/callback_helpers.h"
18 #include "base/compiler_specific.h" 19 #include "base/compiler_specific.h"
19 #include "base/format_macros.h" 20 #include "base/format_macros.h"
20 #include "base/location.h" 21 #include "base/location.h"
21 #include "base/macros.h" 22 #include "base/macros.h"
22 #include "base/metrics/histogram_macros.h" 23 #include "base/metrics/histogram_macros.h"
23 #include "base/metrics/sparse_histogram.h" 24 #include "base/metrics/sparse_histogram.h"
24 #include "base/single_thread_task_runner.h" 25 #include "base/single_thread_task_runner.h"
25 #include "base/strings/string_number_conversions.h" // For HexEncode. 26 #include "base/strings/string_number_conversions.h" // For HexEncode.
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 fail_conditionalization_for_test_(false), 184 fail_conditionalization_for_test_(false),
184 io_buf_len_(0), 185 io_buf_len_(0),
185 read_offset_(0), 186 read_offset_(0),
186 effective_load_flags_(0), 187 effective_load_flags_(0),
187 write_len_(0), 188 write_len_(0),
188 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED), 189 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED),
189 validation_cause_(VALIDATION_CAUSE_UNDEFINED), 190 validation_cause_(VALIDATION_CAUSE_UNDEFINED),
190 total_received_bytes_(0), 191 total_received_bytes_(0),
191 total_sent_bytes_(0), 192 total_sent_bytes_(0),
192 websocket_handshake_stream_base_create_helper_(NULL), 193 websocket_handshake_stream_base_create_helper_(NULL),
194 in_do_loop_(false),
193 weak_factory_(this) { 195 weak_factory_(this) {
194 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction"); 196 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction");
195 static_assert(HttpCache::Transaction::kNumValidationHeaders == 197 static_assert(HttpCache::Transaction::kNumValidationHeaders ==
196 arraysize(kValidationHeaders), 198 arraysize(kValidationHeaders),
197 "invalid number of validation headers"); 199 "invalid number of validation headers");
198 200
199 io_callback_ = base::Bind(&Transaction::OnIOComplete, 201 io_callback_ = base::Bind(&Transaction::OnIOComplete,
200 weak_factory_.GetWeakPtr()); 202 weak_factory_.GetWeakPtr());
201 } 203 }
202 204
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 // 709 //
708 // Read(): 710 // Read():
709 // CacheReadData* 711 // CacheReadData*
710 // 712 //
711 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: 713 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true:
712 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between 714 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between
713 // CacheReadResponse* and CacheDispatchValidation. 715 // CacheReadResponse* and CacheDispatchValidation.
714 int HttpCache::Transaction::DoLoop(int result) { 716 int HttpCache::Transaction::DoLoop(int result) {
715 DCHECK_NE(STATE_UNSET, next_state_); 717 DCHECK_NE(STATE_UNSET, next_state_);
716 DCHECK_NE(STATE_NONE, next_state_); 718 DCHECK_NE(STATE_NONE, next_state_);
719 DCHECK(!in_do_loop_);
717 720
718 int rv = result; 721 int rv = result;
719 do { 722 do {
720 State state = next_state_; 723 State state = next_state_;
721 next_state_ = STATE_UNSET; 724 next_state_ = STATE_UNSET;
725 base::AutoReset<bool> scoped_in_do_loop(&in_do_loop_, true);
726
722 switch (state) { 727 switch (state) {
723 case STATE_GET_BACKEND: 728 case STATE_GET_BACKEND:
724 DCHECK_EQ(OK, rv); 729 DCHECK_EQ(OK, rv);
725 rv = DoGetBackend(); 730 rv = DoGetBackend();
726 break; 731 break;
727 case STATE_GET_BACKEND_COMPLETE: 732 case STATE_GET_BACKEND_COMPLETE:
728 rv = DoGetBackendComplete(rv); 733 rv = DoGetBackendComplete(rv);
729 break; 734 break;
730 case STATE_INIT_ENTRY: 735 case STATE_INIT_ENTRY:
731 DCHECK_EQ(OK, rv); 736 DCHECK_EQ(OK, rv);
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 if (rv != ERR_IO_PENDING && !callback_.is_null()) { 896 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
892 read_buf_ = NULL; // Release the buffer before invoking the callback. 897 read_buf_ = NULL; // Release the buffer before invoking the callback.
893 base::ResetAndReturn(&callback_).Run(rv); 898 base::ResetAndReturn(&callback_).Run(rv);
894 } 899 }
895 900
896 return rv; 901 return rv;
897 } 902 }
898 903
899 int HttpCache::Transaction::DoGetBackend() { 904 int HttpCache::Transaction::DoGetBackend() {
900 cache_pending_ = true; 905 cache_pending_ = true;
901 next_state_ = STATE_GET_BACKEND_COMPLETE; 906 TransitionToState(STATE_GET_BACKEND_COMPLETE);
902 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND); 907 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND);
903 return cache_->GetBackendForTransaction(this); 908 return cache_->GetBackendForTransaction(this);
904 } 909 }
905 910
906 int HttpCache::Transaction::DoGetBackendComplete(int result) { 911 int HttpCache::Transaction::DoGetBackendComplete(int result) {
907 DCHECK(result == OK || result == ERR_FAILED); 912 DCHECK(result == OK || result == ERR_FAILED);
908 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_GET_BACKEND, 913 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_GET_BACKEND,
909 result); 914 result);
910 cache_pending_ = false; 915 cache_pending_ = false;
911 916
912 if (!ShouldPassThrough()) { 917 if (!ShouldPassThrough()) {
913 cache_key_ = cache_->GenerateCacheKey(request_); 918 cache_key_ = cache_->GenerateCacheKey(request_);
914 919
915 // Requested cache access mode. 920 // Requested cache access mode.
916 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { 921 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) {
917 if (effective_load_flags_ & LOAD_BYPASS_CACHE) { 922 if (effective_load_flags_ & LOAD_BYPASS_CACHE) {
918 // The client has asked for nonsense. 923 // The client has asked for nonsense.
919 next_state_ = STATE_NONE; 924 TransitionToState(STATE_NONE);
920 return ERR_CACHE_MISS; 925 return ERR_CACHE_MISS;
921 } 926 }
922 mode_ = READ; 927 mode_ = READ;
923 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { 928 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) {
924 mode_ = WRITE; 929 mode_ = WRITE;
925 } else { 930 } else {
926 mode_ = READ_WRITE; 931 mode_ = READ_WRITE;
927 } 932 }
928 933
929 // Downgrade to UPDATE if the request has been externally conditionalized. 934 // Downgrade to UPDATE if the request has been externally conditionalized.
(...skipping 18 matching lines...) Expand all
948 // transaction behaves the same for GET and HEAD requests at this point: if it 953 // transaction behaves the same for GET and HEAD requests at this point: if it
949 // was not modified, the entry is updated and a response is not returned from 954 // was not modified, the entry is updated and a response is not returned from
950 // the cache. If we receive 200, it doesn't matter if there was a validation 955 // the cache. If we receive 200, it doesn't matter if there was a validation
951 // header or not. 956 // header or not.
952 if (request_->method == "HEAD" && mode_ == WRITE) 957 if (request_->method == "HEAD" && mode_ == WRITE)
953 mode_ = NONE; 958 mode_ = NONE;
954 959
955 // If must use cache, then we must fail. This can happen for back/forward 960 // If must use cache, then we must fail. This can happen for back/forward
956 // navigations to a page generated via a form post. 961 // navigations to a page generated via a form post.
957 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { 962 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) {
958 next_state_ = STATE_NONE; 963 TransitionToState(STATE_NONE);
959 return ERR_CACHE_MISS; 964 return ERR_CACHE_MISS;
960 } 965 }
961 966
962 if (mode_ == NONE) { 967 if (mode_ == NONE) {
963 if (partial_) { 968 if (partial_) {
964 partial_->RestoreHeaders(&custom_request_->extra_headers); 969 partial_->RestoreHeaders(&custom_request_->extra_headers);
965 partial_.reset(); 970 partial_.reset();
966 } 971 }
967 next_state_ = STATE_SEND_REQUEST; 972 TransitionToState(STATE_SEND_REQUEST);
968 } else { 973 } else {
969 next_state_ = STATE_INIT_ENTRY; 974 TransitionToState(STATE_INIT_ENTRY);
970 } 975 }
971 976
972 // This is only set if we have something to do with the response. 977 // This is only set if we have something to do with the response.
973 range_requested_ = (partial_.get() != NULL); 978 range_requested_ = (partial_.get() != NULL);
974 979
975 return OK; 980 return OK;
976 } 981 }
977 982
978 int HttpCache::Transaction::DoInitEntry() { 983 int HttpCache::Transaction::DoInitEntry() {
979 TRACE_EVENT0("io", "HttpCacheTransaction::DoInitEntry"); 984 TRACE_EVENT0("io", "HttpCacheTransaction::DoInitEntry");
980 DCHECK(!new_entry_); 985 DCHECK(!new_entry_);
981 986
982 if (!cache_.get()) { 987 if (!cache_.get()) {
983 next_state_ = STATE_NONE; 988 TransitionToState(STATE_NONE);
984 return ERR_UNEXPECTED; 989 return ERR_UNEXPECTED;
985 } 990 }
986 991
987 if (mode_ == WRITE) { 992 if (mode_ == WRITE) {
988 next_state_ = STATE_DOOM_ENTRY; 993 TransitionToState(STATE_DOOM_ENTRY);
989 return OK; 994 return OK;
990 } 995 }
991 996
992 next_state_ = STATE_OPEN_ENTRY; 997 TransitionToState(STATE_OPEN_ENTRY);
993 return OK; 998 return OK;
994 } 999 }
995 1000
996 int HttpCache::Transaction::DoOpenEntry() { 1001 int HttpCache::Transaction::DoOpenEntry() {
997 TRACE_EVENT0("io", "HttpCacheTransaction::DoOpenEntry"); 1002 TRACE_EVENT0("io", "HttpCacheTransaction::DoOpenEntry");
998 DCHECK(!new_entry_); 1003 DCHECK(!new_entry_);
999 next_state_ = STATE_OPEN_ENTRY_COMPLETE; 1004 TransitionToState(STATE_OPEN_ENTRY_COMPLETE);
1000 cache_pending_ = true; 1005 cache_pending_ = true;
1001 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_OPEN_ENTRY); 1006 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_OPEN_ENTRY);
1002 first_cache_access_since_ = TimeTicks::Now(); 1007 first_cache_access_since_ = TimeTicks::Now();
1003 return cache_->OpenEntry(cache_key_, &new_entry_, this); 1008 return cache_->OpenEntry(cache_key_, &new_entry_, this);
1004 } 1009 }
1005 1010
1006 int HttpCache::Transaction::DoOpenEntryComplete(int result) { 1011 int HttpCache::Transaction::DoOpenEntryComplete(int result) {
1007 TRACE_EVENT0("io", "HttpCacheTransaction::DoOpenEntryComplete"); 1012 TRACE_EVENT0("io", "HttpCacheTransaction::DoOpenEntryComplete");
1008 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is 1013 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is
1009 // OK, otherwise the cache will end up with an active entry without any 1014 // OK, otherwise the cache will end up with an active entry without any
1010 // transaction attached. 1015 // transaction attached.
1011 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_OPEN_ENTRY, 1016 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_OPEN_ENTRY,
1012 result); 1017 result);
1013 cache_pending_ = false; 1018 cache_pending_ = false;
1014 if (result == OK) { 1019 if (result == OK) {
1015 next_state_ = STATE_ADD_TO_ENTRY; 1020 TransitionToState(STATE_ADD_TO_ENTRY);
1016 return OK; 1021 return OK;
1017 } 1022 }
1018 1023
1019 if (result == ERR_CACHE_RACE) { 1024 if (result == ERR_CACHE_RACE) {
1020 next_state_ = STATE_INIT_ENTRY; 1025 TransitionToState(STATE_INIT_ENTRY);
1021 return OK; 1026 return OK;
1022 } 1027 }
1023 1028
1024 if (request_->method == "PUT" || request_->method == "DELETE" || 1029 if (request_->method == "PUT" || request_->method == "DELETE" ||
1025 (request_->method == "HEAD" && mode_ == READ_WRITE)) { 1030 (request_->method == "HEAD" && mode_ == READ_WRITE)) {
1026 DCHECK(mode_ == READ_WRITE || mode_ == WRITE || request_->method == "HEAD"); 1031 DCHECK(mode_ == READ_WRITE || mode_ == WRITE || request_->method == "HEAD");
1027 mode_ = NONE; 1032 mode_ = NONE;
1028 next_state_ = STATE_SEND_REQUEST; 1033 TransitionToState(STATE_SEND_REQUEST);
1029 return OK; 1034 return OK;
1030 } 1035 }
1031 1036
1032 if (mode_ == READ_WRITE) { 1037 if (mode_ == READ_WRITE) {
1033 mode_ = WRITE; 1038 mode_ = WRITE;
1034 next_state_ = STATE_CREATE_ENTRY; 1039 TransitionToState(STATE_CREATE_ENTRY);
1035 return OK; 1040 return OK;
1036 } 1041 }
1037 if (mode_ == UPDATE) { 1042 if (mode_ == UPDATE) {
1038 // There is no cache entry to update; proceed without caching. 1043 // There is no cache entry to update; proceed without caching.
1039 mode_ = NONE; 1044 mode_ = NONE;
1040 next_state_ = STATE_SEND_REQUEST; 1045 TransitionToState(STATE_SEND_REQUEST);
1041 return OK; 1046 return OK;
1042 } 1047 }
1043 1048
1044 // The entry does not exist, and we are not permitted to create a new entry, 1049 // The entry does not exist, and we are not permitted to create a new entry,
1045 // so we must fail. 1050 // so we must fail.
1046 next_state_ = STATE_NONE; 1051 TransitionToState(STATE_NONE);
1047 return ERR_CACHE_MISS; 1052 return ERR_CACHE_MISS;
1048 } 1053 }
1049 1054
1050 int HttpCache::Transaction::DoDoomEntry() { 1055 int HttpCache::Transaction::DoDoomEntry() {
1051 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntry"); 1056 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntry");
1052 next_state_ = STATE_DOOM_ENTRY_COMPLETE; 1057 TransitionToState(STATE_DOOM_ENTRY_COMPLETE);
1053 cache_pending_ = true; 1058 cache_pending_ = true;
1054 if (first_cache_access_since_.is_null()) 1059 if (first_cache_access_since_.is_null())
1055 first_cache_access_since_ = TimeTicks::Now(); 1060 first_cache_access_since_ = TimeTicks::Now();
1056 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_DOOM_ENTRY); 1061 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_DOOM_ENTRY);
1057 return cache_->DoomEntry(cache_key_, this); 1062 return cache_->DoomEntry(cache_key_, this);
1058 } 1063 }
1059 1064
1060 int HttpCache::Transaction::DoDoomEntryComplete(int result) { 1065 int HttpCache::Transaction::DoDoomEntryComplete(int result) {
1061 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntryComplete"); 1066 TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntryComplete");
1062 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_DOOM_ENTRY, 1067 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_DOOM_ENTRY,
1063 result); 1068 result);
1064 next_state_ = STATE_CREATE_ENTRY;
1065 cache_pending_ = false; 1069 cache_pending_ = false;
1066 if (result == ERR_CACHE_RACE) 1070 TransitionToState(result == ERR_CACHE_RACE ? STATE_INIT_ENTRY
1067 next_state_ = STATE_INIT_ENTRY; 1071 : STATE_CREATE_ENTRY);
1068 return OK; 1072 return OK;
1069 } 1073 }
1070 1074
1071 int HttpCache::Transaction::DoCreateEntry() { 1075 int HttpCache::Transaction::DoCreateEntry() {
1072 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntry"); 1076 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntry");
1073 DCHECK(!new_entry_); 1077 DCHECK(!new_entry_);
1074 next_state_ = STATE_CREATE_ENTRY_COMPLETE; 1078 TransitionToState(STATE_CREATE_ENTRY_COMPLETE);
1075 cache_pending_ = true; 1079 cache_pending_ = true;
1076 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_CREATE_ENTRY); 1080 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_CREATE_ENTRY);
1077 return cache_->CreateEntry(cache_key_, &new_entry_, this); 1081 return cache_->CreateEntry(cache_key_, &new_entry_, this);
1078 } 1082 }
1079 1083
1080 int HttpCache::Transaction::DoCreateEntryComplete(int result) { 1084 int HttpCache::Transaction::DoCreateEntryComplete(int result) {
1081 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntryComplete"); 1085 TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntryComplete");
1082 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is 1086 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is
1083 // OK, otherwise the cache will end up with an active entry without any 1087 // OK, otherwise the cache will end up with an active entry without any
1084 // transaction attached. 1088 // transaction attached.
1085 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_CREATE_ENTRY, 1089 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_CREATE_ENTRY,
1086 result); 1090 result);
1087 cache_pending_ = false; 1091 cache_pending_ = false;
1088 switch (result) { 1092 switch (result) {
1089 case OK: 1093 case OK:
1090 next_state_ = STATE_ADD_TO_ENTRY; 1094 TransitionToState(STATE_ADD_TO_ENTRY);
1091 break; 1095 break;
1092 1096
1093 case ERR_CACHE_RACE: 1097 case ERR_CACHE_RACE:
1094 next_state_ = STATE_INIT_ENTRY; 1098 TransitionToState(STATE_INIT_ENTRY);
1095 break; 1099 break;
1096 1100
1097 default: 1101 default:
1098 // We have a race here: Maybe we failed to open the entry and decided to 1102 // We have a race here: Maybe we failed to open the entry and decided to
1099 // create one, but by the time we called create, another transaction 1103 // create one, but by the time we called create, another transaction
1100 // already created the entry. If we want to eliminate this issue, we 1104 // already created the entry. If we want to eliminate this issue, we
1101 // need an atomic OpenOrCreate() method exposed by the disk cache. 1105 // need an atomic OpenOrCreate() method exposed by the disk cache.
1102 DLOG(WARNING) << "Unable to create cache entry"; 1106 DLOG(WARNING) << "Unable to create cache entry";
1103 mode_ = NONE; 1107 mode_ = NONE;
1104 if (partial_) 1108 if (partial_)
1105 partial_->RestoreHeaders(&custom_request_->extra_headers); 1109 partial_->RestoreHeaders(&custom_request_->extra_headers);
1106 next_state_ = STATE_SEND_REQUEST; 1110 TransitionToState(STATE_SEND_REQUEST);
1107 } 1111 }
1108 return OK; 1112 return OK;
1109 } 1113 }
1110 1114
1111 int HttpCache::Transaction::DoAddToEntry() { 1115 int HttpCache::Transaction::DoAddToEntry() {
1112 TRACE_EVENT0("io", "HttpCacheTransaction::DoAddToEntry"); 1116 TRACE_EVENT0("io", "HttpCacheTransaction::DoAddToEntry");
1113 DCHECK(new_entry_); 1117 DCHECK(new_entry_);
1114 cache_pending_ = true; 1118 cache_pending_ = true;
1115 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; 1119 TransitionToState(STATE_ADD_TO_ENTRY_COMPLETE);
1116 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY); 1120 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY);
1117 DCHECK(entry_lock_waiting_since_.is_null()); 1121 DCHECK(entry_lock_waiting_since_.is_null());
1118 entry_lock_waiting_since_ = TimeTicks::Now(); 1122 entry_lock_waiting_since_ = TimeTicks::Now();
1119 int rv = cache_->AddTransactionToEntry(new_entry_, this); 1123 int rv = cache_->AddTransactionToEntry(new_entry_, this);
1120 if (rv == ERR_IO_PENDING) { 1124 if (rv == ERR_IO_PENDING) {
1121 if (bypass_lock_for_test_) { 1125 if (bypass_lock_for_test_) {
1122 OnAddToEntryTimeout(entry_lock_waiting_since_); 1126 base::ThreadTaskRunnerHandle::Get()->PostTask(
1127 FROM_HERE,
1128 base::Bind(&HttpCache::Transaction::OnAddToEntryTimeout,
1129 weak_factory_.GetWeakPtr(), entry_lock_waiting_since_));
1123 } else { 1130 } else {
1124 int timeout_milliseconds = 20 * 1000; 1131 int timeout_milliseconds = 20 * 1000;
1125 if (partial_ && new_entry_->writer && 1132 if (partial_ && new_entry_->writer &&
1126 new_entry_->writer->range_requested_) { 1133 new_entry_->writer->range_requested_) {
1127 // Quickly timeout and bypass the cache if we're a range request and 1134 // Quickly timeout and bypass the cache if we're a range request and
1128 // we're blocked by the reader/writer lock. Doing so eliminates a long 1135 // we're blocked by the reader/writer lock. Doing so eliminates a long
1129 // running issue, http://crbug.com/31014, where two of the same media 1136 // running issue, http://crbug.com/31014, where two of the same media
1130 // resources could not be played back simultaneously due to one locking 1137 // resources could not be played back simultaneously due to one locking
1131 // the cache entry until the entire video was downloaded. 1138 // the cache entry until the entire video was downloaded.
1132 // 1139 //
(...skipping 29 matching lines...) Expand all
1162 DCHECK(new_entry_); 1169 DCHECK(new_entry_);
1163 cache_pending_ = false; 1170 cache_pending_ = false;
1164 1171
1165 if (result == OK) 1172 if (result == OK)
1166 entry_ = new_entry_; 1173 entry_ = new_entry_;
1167 1174
1168 // If there is a failure, the cache should have taken care of new_entry_. 1175 // If there is a failure, the cache should have taken care of new_entry_.
1169 new_entry_ = NULL; 1176 new_entry_ = NULL;
1170 1177
1171 if (result == ERR_CACHE_RACE) { 1178 if (result == ERR_CACHE_RACE) {
1172 next_state_ = STATE_INIT_ENTRY; 1179 TransitionToState(STATE_INIT_ENTRY);
1173 return OK; 1180 return OK;
1174 } 1181 }
1175 1182
1176 if (result == ERR_CACHE_LOCK_TIMEOUT) { 1183 if (result == ERR_CACHE_LOCK_TIMEOUT) {
1177 if (mode_ == READ) { 1184 if (mode_ == READ) {
1178 next_state_ = STATE_NONE; 1185 TransitionToState(STATE_NONE);
1179 return ERR_CACHE_MISS; 1186 return ERR_CACHE_MISS;
1180 } 1187 }
1181 1188
1182 // The cache is busy, bypass it for this transaction. 1189 // The cache is busy, bypass it for this transaction.
1183 mode_ = NONE; 1190 mode_ = NONE;
1184 next_state_ = STATE_SEND_REQUEST; 1191 TransitionToState(STATE_SEND_REQUEST);
1185 if (partial_) { 1192 if (partial_) {
1186 partial_->RestoreHeaders(&custom_request_->extra_headers); 1193 partial_->RestoreHeaders(&custom_request_->extra_headers);
1187 partial_.reset(); 1194 partial_.reset();
1188 } 1195 }
1189 return OK; 1196 return OK;
1190 } 1197 }
1191 1198
1192 open_entry_last_used_ = entry_->disk_entry->GetLastUsed(); 1199 open_entry_last_used_ = entry_->disk_entry->GetLastUsed();
1193 1200
1194 // TODO(jkarlin): We should either handle the case or DCHECK. 1201 // TODO(jkarlin): We should either handle the case or DCHECK.
1195 if (result != OK) { 1202 if (result != OK) {
1196 NOTREACHED(); 1203 NOTREACHED();
1197 next_state_ = STATE_NONE; 1204 TransitionToState(STATE_NONE);
1198 return result; 1205 return result;
1199 } 1206 }
1200 1207
1201 if (mode_ == WRITE) { 1208 if (mode_ == WRITE) {
1202 if (partial_) 1209 if (partial_)
1203 partial_->RestoreHeaders(&custom_request_->extra_headers); 1210 partial_->RestoreHeaders(&custom_request_->extra_headers);
1204 next_state_ = STATE_SEND_REQUEST; 1211 TransitionToState(STATE_SEND_REQUEST);
1205 } else { 1212 } else {
1206 // We have to read the headers from the cached entry. 1213 // We have to read the headers from the cached entry.
1207 DCHECK(mode_ & READ_META); 1214 DCHECK(mode_ & READ_META);
1208 next_state_ = STATE_CACHE_READ_RESPONSE; 1215 TransitionToState(STATE_CACHE_READ_RESPONSE);
1209 } 1216 }
1210 return OK; 1217 return OK;
1211 } 1218 }
1212 1219
1213 int HttpCache::Transaction::DoCacheReadResponse() { 1220 int HttpCache::Transaction::DoCacheReadResponse() {
1214 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadResponse"); 1221 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadResponse");
1215 DCHECK(entry_); 1222 DCHECK(entry_);
1216 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE; 1223 TransitionToState(STATE_CACHE_READ_RESPONSE_COMPLETE);
1217 1224
1218 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex); 1225 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex);
1219 read_buf_ = new IOBuffer(io_buf_len_); 1226 read_buf_ = new IOBuffer(io_buf_len_);
1220 1227
1221 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO); 1228 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO);
1222 return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(), 1229 return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(),
1223 io_buf_len_, io_callback_); 1230 io_buf_len_, io_callback_);
1224 } 1231 }
1225 1232
1226 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { 1233 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
(...skipping 20 matching lines...) Expand all
1247 // cache should not be storing multi gigabyte resources. See 1254 // cache should not be storing multi gigabyte resources. See
1248 // http://crbug.com/89567. 1255 // http://crbug.com/89567.
1249 if ((truncated_ || response_.headers->response_code() == 206) && 1256 if ((truncated_ || response_.headers->response_code() == 206) &&
1250 !range_requested_ && 1257 !range_requested_ &&
1251 full_response_length > std::numeric_limits<int32_t>::max()) { 1258 full_response_length > std::numeric_limits<int32_t>::max()) {
1252 // Does not release the cache entry. If another transaction wants to use 1259 // Does not release the cache entry. If another transaction wants to use
1253 // this cache entry while this transaction is active, the second transaction 1260 // this cache entry while this transaction is active, the second transaction
1254 // will fall back to the network after the timeout. 1261 // will fall back to the network after the timeout.
1255 DCHECK(!partial_); 1262 DCHECK(!partial_);
1256 mode_ = NONE; 1263 mode_ = NONE;
1257 next_state_ = STATE_SEND_REQUEST; 1264 TransitionToState(STATE_SEND_REQUEST);
1258 return OK; 1265 return OK;
1259 } 1266 }
1260 1267
1261 if (response_.unused_since_prefetch != 1268 if (response_.unused_since_prefetch !=
1262 !!(request_->load_flags & LOAD_PREFETCH)) { 1269 !!(request_->load_flags & LOAD_PREFETCH)) {
1263 // Either this is the first use of an entry since it was prefetched XOR 1270 // Either this is the first use of an entry since it was prefetched XOR
1264 // this is a prefetch. The value of response.unused_since_prefetch is 1271 // this is a prefetch. The value of response.unused_since_prefetch is
1265 // valid for this transaction but the bit needs to be flipped in storage. 1272 // valid for this transaction but the bit needs to be flipped in storage.
1266 next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH; 1273 TransitionToState(STATE_TOGGLE_UNUSED_SINCE_PREFETCH);
1267 return OK; 1274 return OK;
1268 } 1275 }
1269 1276
1270 next_state_ = STATE_CACHE_DISPATCH_VALIDATION; 1277 TransitionToState(STATE_CACHE_DISPATCH_VALIDATION);
1271 return OK; 1278 return OK;
1272 } 1279 }
1273 1280
1274 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch() { 1281 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch() {
1275 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheToggleUnusedSincePrefetch"); 1282 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheToggleUnusedSincePrefetch");
1276 // Write back the toggled value for the next use of this entry. 1283 // Write back the toggled value for the next use of this entry.
1277 response_.unused_since_prefetch = !response_.unused_since_prefetch; 1284 response_.unused_since_prefetch = !response_.unused_since_prefetch;
1278 1285
1279 // TODO(jkarlin): If DoUpdateCachedResponse is also called for this 1286 // TODO(jkarlin): If DoUpdateCachedResponse is also called for this
1280 // transaction then metadata will be written to cache twice. If prefetching 1287 // transaction then metadata will be written to cache twice. If prefetching
1281 // becomes more common, consider combining the writes. 1288 // becomes more common, consider combining the writes.
1282 1289
1283 next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE; 1290 TransitionToState(STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE);
1284 return WriteResponseInfoToEntry(false); 1291 return WriteResponseInfoToEntry(false);
1285 } 1292 }
1286 1293
1287 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetchComplete( 1294 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetchComplete(
1288 int result) { 1295 int result) {
1289 TRACE_EVENT0( 1296 TRACE_EVENT0(
1290 kNetTracingCategory, 1297 kNetTracingCategory,
1291 "HttpCacheTransaction::DoCacheToggleUnusedSincePrefetchComplete"); 1298 "HttpCacheTransaction::DoCacheToggleUnusedSincePrefetchComplete");
1292 // Restore the original value for this transaction. 1299 // Restore the original value for this transaction.
1293 response_.unused_since_prefetch = !response_.unused_since_prefetch; 1300 response_.unused_since_prefetch = !response_.unused_since_prefetch;
1294 next_state_ = STATE_CACHE_DISPATCH_VALIDATION; 1301 TransitionToState(STATE_CACHE_DISPATCH_VALIDATION);
1295 return OnWriteResponseInfoToEntryComplete(result); 1302 return OnWriteResponseInfoToEntryComplete(result);
1296 } 1303 }
1297 1304
1298 int HttpCache::Transaction::DoCacheDispatchValidation() { 1305 int HttpCache::Transaction::DoCacheDispatchValidation() {
1299 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheDispatchValidation"); 1306 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheDispatchValidation");
1300 // We now have access to the cache entry. 1307 // We now have access to the cache entry.
1301 // 1308 //
1302 // o if we are a reader for the transaction, then we can start reading the 1309 // o if we are a reader for the transaction, then we can start reading the
1303 // cache entry. 1310 // cache entry.
1304 // 1311 //
(...skipping 18 matching lines...) Expand all
1323 result = BeginExternallyConditionalizedRequest(); 1330 result = BeginExternallyConditionalizedRequest();
1324 break; 1331 break;
1325 case WRITE: 1332 case WRITE:
1326 default: 1333 default:
1327 NOTREACHED(); 1334 NOTREACHED();
1328 } 1335 }
1329 return result; 1336 return result;
1330 } 1337 }
1331 1338
1332 int HttpCache::Transaction::DoCacheQueryData() { 1339 int HttpCache::Transaction::DoCacheQueryData() {
1333 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; 1340 TransitionToState(STATE_CACHE_QUERY_DATA_COMPLETE);
1334 return entry_->disk_entry->ReadyForSparseIO(io_callback_); 1341 return entry_->disk_entry->ReadyForSparseIO(io_callback_);
1335 } 1342 }
1336 1343
1337 int HttpCache::Transaction::DoCacheQueryDataComplete(int result) { 1344 int HttpCache::Transaction::DoCacheQueryDataComplete(int result) {
1338 DCHECK_EQ(OK, result); 1345 DCHECK_EQ(OK, result);
1339 if (!cache_.get()) { 1346 if (!cache_.get()) {
1340 next_state_ = STATE_NONE; 1347 TransitionToState(STATE_NONE);
1341 return ERR_UNEXPECTED; 1348 return ERR_UNEXPECTED;
1342 } 1349 }
1343 1350
1344 return ValidateEntryHeadersAndContinue(); 1351 return ValidateEntryHeadersAndContinue();
1345 } 1352 }
1346 1353
1347 // We may end up here multiple times for a given request. 1354 // We may end up here multiple times for a given request.
1348 int HttpCache::Transaction::DoStartPartialCacheValidation() { 1355 int HttpCache::Transaction::DoStartPartialCacheValidation() {
1349 if (mode_ == NONE) { 1356 if (mode_ == NONE) {
1350 next_state_ = STATE_NONE; 1357 TransitionToState(STATE_NONE);
1351 return OK; 1358 return OK;
1352 } 1359 }
1353 1360
1354 next_state_ = STATE_COMPLETE_PARTIAL_CACHE_VALIDATION; 1361 TransitionToState(STATE_COMPLETE_PARTIAL_CACHE_VALIDATION);
1355 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); 1362 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_);
1356 } 1363 }
1357 1364
1358 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { 1365 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) {
1359 if (!result) { 1366 if (!result) {
1360 // This is the end of the request. 1367 // This is the end of the request.
1361 if (mode_ & WRITE) { 1368 if (mode_ & WRITE) {
1362 DoneWritingToEntry(true); 1369 DoneWritingToEntry(true);
1363 } else { 1370 } else {
1364 cache_->DoneReadingFromEntry(entry_, this); 1371 cache_->DoneReadingFromEntry(entry_, this);
1365 entry_ = NULL; 1372 entry_ = NULL;
1366 } 1373 }
1367 next_state_ = STATE_NONE; 1374 TransitionToState(STATE_NONE);
1368 return result; 1375 return result;
1369 } 1376 }
1370 1377
1371 if (result < 0) { 1378 if (result < 0) {
1372 next_state_ = STATE_NONE; 1379 TransitionToState(STATE_NONE);
1373 return result; 1380 return result;
1374 } 1381 }
1375 1382
1376 partial_->PrepareCacheValidation(entry_->disk_entry, 1383 partial_->PrepareCacheValidation(entry_->disk_entry,
1377 &custom_request_->extra_headers); 1384 &custom_request_->extra_headers);
1378 1385
1379 if (reading_ && partial_->IsCurrentRangeCached()) { 1386 if (reading_ && partial_->IsCurrentRangeCached()) {
1380 next_state_ = STATE_CACHE_READ_DATA; 1387 TransitionToState(STATE_CACHE_READ_DATA);
1381 return OK; 1388 return OK;
1382 } 1389 }
1383 1390
1384 return BeginCacheValidation(); 1391 return BeginCacheValidation();
1385 } 1392 }
1386 1393
1387 int HttpCache::Transaction::DoSendRequest() { 1394 int HttpCache::Transaction::DoSendRequest() {
1388 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequest"); 1395 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequest");
1389 DCHECK(mode_ & WRITE || mode_ == NONE); 1396 DCHECK(mode_ & WRITE || mode_ == NONE);
1390 DCHECK(!network_trans_.get()); 1397 DCHECK(!network_trans_.get());
1391 1398
1392 send_request_since_ = TimeTicks::Now(); 1399 send_request_since_ = TimeTicks::Now();
1393 1400
1394 // Create a network transaction. 1401 // Create a network transaction.
1395 int rv = 1402 int rv =
1396 cache_->network_layer_->CreateTransaction(priority_, &network_trans_); 1403 cache_->network_layer_->CreateTransaction(priority_, &network_trans_);
1397 if (rv != OK) { 1404 if (rv != OK) {
1398 next_state_ = STATE_NONE; 1405 TransitionToState(STATE_NONE);
1399 return rv; 1406 return rv;
1400 } 1407 }
1401 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_); 1408 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_);
1402 network_trans_->SetBeforeHeadersSentCallback(before_headers_sent_callback_); 1409 network_trans_->SetBeforeHeadersSentCallback(before_headers_sent_callback_);
1403 1410
1404 // Old load timing information, if any, is now obsolete. 1411 // Old load timing information, if any, is now obsolete.
1405 old_network_trans_load_timing_.reset(); 1412 old_network_trans_load_timing_.reset();
1406 old_remote_endpoint_ = IPEndPoint(); 1413 old_remote_endpoint_ = IPEndPoint();
1407 1414
1408 if (websocket_handshake_stream_base_create_helper_) 1415 if (websocket_handshake_stream_base_create_helper_)
1409 network_trans_->SetWebSocketHandshakeStreamCreateHelper( 1416 network_trans_->SetWebSocketHandshakeStreamCreateHelper(
1410 websocket_handshake_stream_base_create_helper_); 1417 websocket_handshake_stream_base_create_helper_);
1411 1418
1412 next_state_ = STATE_SEND_REQUEST_COMPLETE; 1419 TransitionToState(STATE_SEND_REQUEST_COMPLETE);
1413 rv = network_trans_->Start(request_, io_callback_, net_log_); 1420 rv = network_trans_->Start(request_, io_callback_, net_log_);
1414 return rv; 1421 return rv;
1415 } 1422 }
1416 1423
1417 int HttpCache::Transaction::DoSendRequestComplete(int result) { 1424 int HttpCache::Transaction::DoSendRequestComplete(int result) {
1418 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequestComplete"); 1425 TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequestComplete");
1419 if (!cache_.get()) { 1426 if (!cache_.get()) {
1420 next_state_ = STATE_NONE; 1427 TransitionToState(STATE_NONE);
1421 return ERR_UNEXPECTED; 1428 return ERR_UNEXPECTED;
1422 } 1429 }
1423 1430
1424 // If we tried to conditionalize the request and failed, we know 1431 // If we tried to conditionalize the request and failed, we know
1425 // we won't be reading from the cache after this point. 1432 // we won't be reading from the cache after this point.
1426 if (couldnt_conditionalize_request_) 1433 if (couldnt_conditionalize_request_)
1427 mode_ = WRITE; 1434 mode_ = WRITE;
1428 1435
1429 if (result == OK) { 1436 if (result == OK) {
1430 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; 1437 TransitionToState(STATE_SUCCESSFUL_SEND_REQUEST);
1431 return OK; 1438 return OK;
1432 } 1439 }
1433 1440
1434 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); 1441 const HttpResponseInfo* response = network_trans_->GetResponseInfo();
1435 response_.network_accessed = response->network_accessed; 1442 response_.network_accessed = response->network_accessed;
1436 1443
1437 // Do not record requests that have network errors or restarts. 1444 // Do not record requests that have network errors or restarts.
1438 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); 1445 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
1439 if (IsCertificateError(result)) { 1446 if (IsCertificateError(result)) {
1440 // If we get a certificate error, then there is a certificate in ssl_info, 1447 // If we get a certificate error, then there is a certificate in ssl_info,
1441 // so GetResponseInfo() should never return NULL here. 1448 // so GetResponseInfo() should never return NULL here.
1442 DCHECK(response); 1449 DCHECK(response);
1443 response_.ssl_info = response->ssl_info; 1450 response_.ssl_info = response->ssl_info;
1444 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 1451 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
1445 DCHECK(response); 1452 DCHECK(response);
1446 response_.cert_request_info = response->cert_request_info; 1453 response_.cert_request_info = response->cert_request_info;
1447 } else if (response_.was_cached) { 1454 } else if (response_.was_cached) {
1448 DoneWritingToEntry(true); 1455 DoneWritingToEntry(true);
1449 } 1456 }
1450 1457
1451 next_state_ = STATE_NONE; 1458 TransitionToState(STATE_NONE);
1452 return result; 1459 return result;
1453 } 1460 }
1454 1461
1455 // We received the response headers and there is no error. 1462 // We received the response headers and there is no error.
1456 int HttpCache::Transaction::DoSuccessfulSendRequest() { 1463 int HttpCache::Transaction::DoSuccessfulSendRequest() {
1457 TRACE_EVENT0("io", "HttpCacheTransaction::DoSuccessfulSendRequest"); 1464 TRACE_EVENT0("io", "HttpCacheTransaction::DoSuccessfulSendRequest");
1458 DCHECK(!new_response_); 1465 DCHECK(!new_response_);
1459 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); 1466 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo();
1460 1467
1461 if (new_response->headers->response_code() == 401 || 1468 if (new_response->headers->response_code() == 401 ||
1462 new_response->headers->response_code() == 407) { 1469 new_response->headers->response_code() == 407) {
1463 SetAuthResponse(*new_response); 1470 SetAuthResponse(*new_response);
1464 if (!reading_) { 1471 if (!reading_) {
1465 next_state_ = STATE_NONE; 1472 TransitionToState(STATE_NONE);
1466 return OK; 1473 return OK;
1467 } 1474 }
1468 1475
1469 // We initiated a second request the caller doesn't know about. We should be 1476 // We initiated a second request the caller doesn't know about. We should be
1470 // able to authenticate this request because we should have authenticated 1477 // able to authenticate this request because we should have authenticated
1471 // this URL moments ago. 1478 // this URL moments ago.
1472 if (IsReadyToRestartForAuth()) { 1479 if (IsReadyToRestartForAuth()) {
1473 DCHECK(!response_.auth_challenge.get()); 1480 DCHECK(!response_.auth_challenge.get());
1474 next_state_ = STATE_SEND_REQUEST_COMPLETE; 1481 TransitionToState(STATE_SEND_REQUEST_COMPLETE);
1475 // In theory we should check to see if there are new cookies, but there 1482 // In theory we should check to see if there are new cookies, but there
1476 // is no way to do that from here. 1483 // is no way to do that from here.
1477 return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_); 1484 return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_);
1478 } 1485 }
1479 1486
1480 // We have to perform cleanup at this point so that at least the next 1487 // We have to perform cleanup at this point so that at least the next
1481 // request can succeed. We do not retry at this point, because data 1488 // request can succeed. We do not retry at this point, because data
1482 // has been read and we have no way to gather credentials. We would 1489 // has been read and we have no way to gather credentials. We would
1483 // fail again, and potentially loop. This can happen if the credentials 1490 // fail again, and potentially loop. This can happen if the credentials
1484 // expire while chrome is suspended. 1491 // expire while chrome is suspended.
1485 if (entry_) 1492 if (entry_)
1486 DoomPartialEntry(false); 1493 DoomPartialEntry(false);
1487 mode_ = NONE; 1494 mode_ = NONE;
1488 partial_.reset(); 1495 partial_.reset();
1489 ResetNetworkTransaction(); 1496 ResetNetworkTransaction();
1490 next_state_ = STATE_NONE; 1497 TransitionToState(STATE_NONE);
1491 return ERR_CACHE_AUTH_FAILURE_AFTER_READ; 1498 return ERR_CACHE_AUTH_FAILURE_AFTER_READ;
1492 } 1499 }
1493 1500
1494 new_response_ = new_response; 1501 new_response_ = new_response;
1495 if (!ValidatePartialResponse() && !auth_response_.headers.get()) { 1502 if (!ValidatePartialResponse() && !auth_response_.headers.get()) {
1496 // Something went wrong with this request and we have to restart it. 1503 // Something went wrong with this request and we have to restart it.
1497 // If we have an authentication response, we are exposed to weird things 1504 // If we have an authentication response, we are exposed to weird things
1498 // hapenning if the user cancels the authentication before we receive 1505 // hapenning if the user cancels the authentication before we receive
1499 // the new response. 1506 // the new response.
1500 net_log_.AddEvent(NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); 1507 net_log_.AddEvent(NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST);
1501 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); 1508 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
1502 SetResponse(HttpResponseInfo()); 1509 SetResponse(HttpResponseInfo());
1503 ResetNetworkTransaction(); 1510 ResetNetworkTransaction();
1504 new_response_ = NULL; 1511 new_response_ = NULL;
1505 next_state_ = STATE_SEND_REQUEST; 1512 TransitionToState(STATE_SEND_REQUEST);
1506 return OK; 1513 return OK;
1507 } 1514 }
1508 1515
1509 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { 1516 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) {
1510 // We have stored the full entry, but it changed and the server is 1517 // We have stored the full entry, but it changed and the server is
1511 // sending a range. We have to delete the old entry. 1518 // sending a range. We have to delete the old entry.
1512 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); 1519 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
1513 DoneWritingToEntry(false); 1520 DoneWritingToEntry(false);
1514 } 1521 }
1515 1522
(...skipping 20 matching lines...) Expand all
1536 NonErrorResponse(new_response->headers->response_code())) { 1543 NonErrorResponse(new_response->headers->response_code())) {
1537 cache_->DoomMainEntryForUrl(request_->url); 1544 cache_->DoomMainEntryForUrl(request_->url);
1538 } 1545 }
1539 1546
1540 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); 1547 RecordNoStoreHeaderHistogram(request_->load_flags, new_response);
1541 1548
1542 if (new_response_->headers->response_code() == 416 && 1549 if (new_response_->headers->response_code() == 416 &&
1543 (request_->method == "GET" || request_->method == "POST")) { 1550 (request_->method == "GET" || request_->method == "POST")) {
1544 // If there is an active entry it may be destroyed with this transaction. 1551 // If there is an active entry it may be destroyed with this transaction.
1545 SetResponse(*new_response_); 1552 SetResponse(*new_response_);
1546 next_state_ = STATE_NONE; 1553 TransitionToState(STATE_NONE);
1547 return OK; 1554 return OK;
1548 } 1555 }
1549 1556
1550 // Are we expecting a response to a conditional query? 1557 // Are we expecting a response to a conditional query?
1551 if (mode_ == READ_WRITE || mode_ == UPDATE) { 1558 if (mode_ == READ_WRITE || mode_ == UPDATE) {
1552 if (new_response->headers->response_code() == 304 || handling_206_) { 1559 if (new_response->headers->response_code() == 304 || handling_206_) {
1553 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); 1560 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED);
1554 next_state_ = STATE_UPDATE_CACHED_RESPONSE; 1561 TransitionToState(STATE_UPDATE_CACHED_RESPONSE);
1555 return OK; 1562 return OK;
1556 } 1563 }
1557 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); 1564 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED);
1558 mode_ = WRITE; 1565 mode_ = WRITE;
1559 } 1566 }
1560 1567
1561 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; 1568 TransitionToState(STATE_OVERWRITE_CACHED_RESPONSE);
1562 return OK; 1569 return OK;
1563 } 1570 }
1564 1571
1565 // We received 304 or 206 and we want to update the cached response headers. 1572 // We received 304 or 206 and we want to update the cached response headers.
1566 int HttpCache::Transaction::DoUpdateCachedResponse() { 1573 int HttpCache::Transaction::DoUpdateCachedResponse() {
1567 TRACE_EVENT0("io", "HttpCacheTransaction::DoUpdateCachedResponse"); 1574 TRACE_EVENT0("io", "HttpCacheTransaction::DoUpdateCachedResponse");
1568 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE;
1569 int rv = OK; 1575 int rv = OK;
1570 // Update the cached response based on the headers and properties of 1576 // Update the cached response based on the headers and properties of
1571 // new_response_. 1577 // new_response_.
1572 response_.headers->Update(*new_response_->headers.get()); 1578 response_.headers->Update(*new_response_->headers.get());
1573 response_.response_time = new_response_->response_time; 1579 response_.response_time = new_response_->response_time;
1574 response_.request_time = new_response_->request_time; 1580 response_.request_time = new_response_->request_time;
1575 response_.network_accessed = new_response_->network_accessed; 1581 response_.network_accessed = new_response_->network_accessed;
1576 response_.unused_since_prefetch = new_response_->unused_since_prefetch; 1582 response_.unused_since_prefetch = new_response_->unused_since_prefetch;
1577 response_.ssl_info = new_response_->ssl_info; 1583 response_.ssl_info = new_response_->ssl_info;
1578 if (new_response_->vary_data.is_valid()) { 1584 if (new_response_->vary_data.is_valid()) {
1579 response_.vary_data = new_response_->vary_data; 1585 response_.vary_data = new_response_->vary_data;
1580 } else if (response_.vary_data.is_valid()) { 1586 } else if (response_.vary_data.is_valid()) {
1581 // There is a vary header in the stored response but not in the current one. 1587 // There is a vary header in the stored response but not in the current one.
1582 // Update the data with the new request headers. 1588 // Update the data with the new request headers.
1583 HttpVaryData new_vary_data; 1589 HttpVaryData new_vary_data;
1584 new_vary_data.Init(*request_, *response_.headers.get()); 1590 new_vary_data.Init(*request_, *response_.headers.get());
1585 response_.vary_data = new_vary_data; 1591 response_.vary_data = new_vary_data;
1586 } 1592 }
1587 1593
1588 if (response_.headers->HasHeaderValue("cache-control", "no-store")) { 1594 if (response_.headers->HasHeaderValue("cache-control", "no-store")) {
1589 if (!entry_->doomed) { 1595 if (!entry_->doomed) {
1590 int ret = cache_->DoomEntry(cache_key_, NULL); 1596 int ret = cache_->DoomEntry(cache_key_, NULL);
1591 DCHECK_EQ(OK, ret); 1597 DCHECK_EQ(OK, ret);
1592 } 1598 }
1599 TransitionToState(STATE_UPDATE_CACHED_RESPONSE_COMPLETE);
1593 } else { 1600 } else {
1594 // If we are already reading, we already updated the headers for this 1601 // If we are already reading, we already updated the headers for this
1595 // request; doing it again will change Content-Length. 1602 // request; doing it again will change Content-Length.
1596 if (!reading_) { 1603 if (!reading_) {
1597 next_state_ = STATE_CACHE_WRITE_UPDATED_RESPONSE; 1604 TransitionToState(STATE_CACHE_WRITE_UPDATED_RESPONSE);
1598 rv = OK; 1605 rv = OK;
1606 } else {
1607 TransitionToState(STATE_UPDATE_CACHED_RESPONSE_COMPLETE);
1599 } 1608 }
1600 } 1609 }
1610
1601 return rv; 1611 return rv;
1602 } 1612 }
1603 1613
1604 int HttpCache::Transaction::DoCacheWriteUpdatedResponse() { 1614 int HttpCache::Transaction::DoCacheWriteUpdatedResponse() {
1605 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteUpdatedResponse"); 1615 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteUpdatedResponse");
1606 1616
1607 next_state_ = STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE; 1617 TransitionToState(STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE);
1608 return WriteResponseInfoToEntry(false); 1618 return WriteResponseInfoToEntry(false);
1609 } 1619 }
1610 1620
1611 int HttpCache::Transaction::DoCacheWriteUpdatedResponseComplete(int result) { 1621 int HttpCache::Transaction::DoCacheWriteUpdatedResponseComplete(int result) {
1612 TRACE_EVENT0("io", 1622 TRACE_EVENT0("io",
1613 "HttpCacheTransaction::DoCacheWriteUpdatedResponseComplete"); 1623 "HttpCacheTransaction::DoCacheWriteUpdatedResponseComplete");
1614 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE; 1624 TransitionToState(STATE_UPDATE_CACHED_RESPONSE_COMPLETE);
1615 return OnWriteResponseInfoToEntryComplete(result); 1625 return OnWriteResponseInfoToEntryComplete(result);
1616 } 1626 }
1617 1627
1618 int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) { 1628 int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) {
1619 TRACE_EVENT0("io", "HttpCacheTransaction::DoUpdateCachedResponseComplete"); 1629 TRACE_EVENT0("io", "HttpCacheTransaction::DoUpdateCachedResponseComplete");
1620 if (mode_ == UPDATE) { 1630 if (mode_ == UPDATE) {
1621 DCHECK(!handling_206_); 1631 DCHECK(!handling_206_);
1622 // We got a "not modified" response and already updated the corresponding 1632 // We got a "not modified" response and already updated the corresponding
1623 // cache entry above. 1633 // cache entry above.
1624 // 1634 //
1625 // By closing the cached entry now, we make sure that the 304 rather than 1635 // By closing the cached entry now, we make sure that the 304 rather than
1626 // the cached 200 response, is what will be returned to the user. 1636 // the cached 200 response, is what will be returned to the user.
1627 DoneWritingToEntry(true); 1637 DoneWritingToEntry(true);
1628 } else if (entry_ && !handling_206_) { 1638 } else if (entry_ && !handling_206_) {
1629 DCHECK_EQ(READ_WRITE, mode_); 1639 DCHECK_EQ(READ_WRITE, mode_);
1630 if (!partial_ || partial_->IsLastRange()) { 1640 if (!partial_ || partial_->IsLastRange()) {
1631 cache_->ConvertWriterToReader(entry_); 1641 cache_->ConvertWriterToReader(entry_);
1632 mode_ = READ; 1642 mode_ = READ;
1633 } 1643 }
1634 // We no longer need the network transaction, so destroy it. 1644 // We no longer need the network transaction, so destroy it.
1635 ResetNetworkTransaction(); 1645 ResetNetworkTransaction();
1636 } else if (entry_ && handling_206_ && truncated_ && 1646 } else if (entry_ && handling_206_ && truncated_ &&
1637 partial_->initial_validation()) { 1647 partial_->initial_validation()) {
1638 // We just finished the validation of a truncated entry, and the server 1648 // We just finished the validation of a truncated entry, and the server
1639 // is willing to resume the operation. Now we go back and start serving 1649 // is willing to resume the operation. Now we go back and start serving
1640 // the first part to the user. 1650 // the first part to the user.
1641 ResetNetworkTransaction(); 1651 ResetNetworkTransaction();
1642 new_response_ = NULL; 1652 new_response_ = NULL;
1643 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; 1653 TransitionToState(STATE_START_PARTIAL_CACHE_VALIDATION);
1644 partial_->SetRangeToStartDownload(); 1654 partial_->SetRangeToStartDownload();
1645 return OK; 1655 return OK;
1646 } 1656 }
1647 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; 1657 TransitionToState(STATE_OVERWRITE_CACHED_RESPONSE);
1648 return OK; 1658 return OK;
1649 } 1659 }
1650 1660
1651 int HttpCache::Transaction::DoOverwriteCachedResponse() { 1661 int HttpCache::Transaction::DoOverwriteCachedResponse() {
1652 TRACE_EVENT0("io", "HttpCacheTransaction::DoOverwriteCachedResponse"); 1662 TRACE_EVENT0("io", "HttpCacheTransaction::DoOverwriteCachedResponse");
1653 if (mode_ & READ) { 1663 if (mode_ & READ) {
1654 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; 1664 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED);
1655 return OK; 1665 return OK;
1656 } 1666 }
1657 1667
1658 // We change the value of Content-Length for partial content. 1668 // We change the value of Content-Length for partial content.
1659 if (handling_206_ && partial_) 1669 if (handling_206_ && partial_)
1660 partial_->FixContentLength(new_response_->headers.get()); 1670 partial_->FixContentLength(new_response_->headers.get());
1661 1671
1662 SetResponse(*new_response_); 1672 SetResponse(*new_response_);
1663 1673
1664 if (request_->method == "HEAD") { 1674 if (request_->method == "HEAD") {
1665 // This response is replacing the cached one. 1675 // This response is replacing the cached one.
1666 DoneWritingToEntry(false); 1676 DoneWritingToEntry(false);
1667 mode_ = NONE; 1677 mode_ = NONE;
1668 new_response_ = NULL; 1678 new_response_ = NULL;
1669 next_state_ = STATE_NONE; 1679 TransitionToState(STATE_NONE);
1670 return OK; 1680 return OK;
1671 } 1681 }
1672 1682
1673 if (handling_206_ && !CanResume(false)) { 1683 if (handling_206_ && !CanResume(false)) {
1674 // There is no point in storing this resource because it will never be used. 1684 // There is no point in storing this resource because it will never be used.
1675 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. 1685 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries.
1676 DoneWritingToEntry(false); 1686 DoneWritingToEntry(false);
1677 if (partial_) 1687 if (partial_)
1678 partial_->FixResponseHeaders(response_.headers.get(), true); 1688 partial_->FixResponseHeaders(response_.headers.get(), true);
1679 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; 1689 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED);
1680 return OK; 1690 return OK;
1681 } 1691 }
1682 1692
1683 next_state_ = STATE_CACHE_WRITE_RESPONSE; 1693 TransitionToState(STATE_CACHE_WRITE_RESPONSE);
1684 return OK; 1694 return OK;
1685 } 1695 }
1686 1696
1687 int HttpCache::Transaction::DoCacheWriteResponse() { 1697 int HttpCache::Transaction::DoCacheWriteResponse() {
1688 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); 1698 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse");
1689 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; 1699 TransitionToState(STATE_CACHE_WRITE_RESPONSE_COMPLETE);
1690 return WriteResponseInfoToEntry(truncated_); 1700 return WriteResponseInfoToEntry(truncated_);
1691 } 1701 }
1692 1702
1693 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { 1703 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) {
1694 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); 1704 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete");
1695 next_state_ = STATE_TRUNCATE_CACHED_DATA; 1705 TransitionToState(STATE_TRUNCATE_CACHED_DATA);
1696 return OnWriteResponseInfoToEntryComplete(result); 1706 return OnWriteResponseInfoToEntryComplete(result);
1697 } 1707 }
1698 1708
1699 int HttpCache::Transaction::DoTruncateCachedData() { 1709 int HttpCache::Transaction::DoTruncateCachedData() {
1700 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); 1710 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData");
1701 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; 1711 TransitionToState(STATE_TRUNCATE_CACHED_DATA_COMPLETE);
1702 if (!entry_) 1712 if (!entry_)
1703 return OK; 1713 return OK;
1704 if (net_log_.IsCapturing()) 1714 if (net_log_.IsCapturing())
1705 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); 1715 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA);
1706 // Truncate the stream. 1716 // Truncate the stream.
1707 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); 1717 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_);
1708 } 1718 }
1709 1719
1710 int HttpCache::Transaction::DoTruncateCachedDataComplete(int result) { 1720 int HttpCache::Transaction::DoTruncateCachedDataComplete(int result) {
1711 TRACE_EVENT0("io", "HttpCacheTransaction::DoInitEntry"); 1721 TRACE_EVENT0("io", "HttpCacheTransaction::DoInitEntry");
1712 if (entry_) { 1722 if (entry_) {
1713 if (net_log_.IsCapturing()) { 1723 if (net_log_.IsCapturing()) {
1714 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, 1724 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA,
1715 result); 1725 result);
1716 } 1726 }
1717 } 1727 }
1718 1728
1719 next_state_ = STATE_TRUNCATE_CACHED_METADATA; 1729 TransitionToState(STATE_TRUNCATE_CACHED_METADATA);
1720 return OK; 1730 return OK;
1721 } 1731 }
1722 1732
1723 int HttpCache::Transaction::DoTruncateCachedMetadata() { 1733 int HttpCache::Transaction::DoTruncateCachedMetadata() {
1724 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedMetadata"); 1734 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedMetadata");
1725 next_state_ = STATE_TRUNCATE_CACHED_METADATA_COMPLETE; 1735 TransitionToState(STATE_TRUNCATE_CACHED_METADATA_COMPLETE);
1726 if (!entry_) 1736 if (!entry_)
1727 return OK; 1737 return OK;
1728 1738
1729 if (net_log_.IsCapturing()) 1739 if (net_log_.IsCapturing())
1730 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); 1740 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO);
1731 return WriteToEntry(kMetadataIndex, 0, NULL, 0, io_callback_); 1741 return WriteToEntry(kMetadataIndex, 0, NULL, 0, io_callback_);
1732 } 1742 }
1733 1743
1734 int HttpCache::Transaction::DoTruncateCachedMetadataComplete(int result) { 1744 int HttpCache::Transaction::DoTruncateCachedMetadataComplete(int result) {
1735 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedMetadataComplete"); 1745 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedMetadataComplete");
1736 if (entry_) { 1746 if (entry_) {
1737 if (net_log_.IsCapturing()) { 1747 if (net_log_.IsCapturing()) {
1738 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, 1748 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO,
1739 result); 1749 result);
1740 } 1750 }
1741 } 1751 }
1742 1752
1743 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; 1753 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED);
1744 return OK; 1754 return OK;
1745 } 1755 }
1746 1756
1747 int HttpCache::Transaction::DoPartialHeadersReceived() { 1757 int HttpCache::Transaction::DoPartialHeadersReceived() {
1748 new_response_ = NULL; 1758 new_response_ = NULL;
1749 1759
1750 if (!partial_) { 1760 if (!partial_) {
1751 if (entry_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) 1761 if (entry_ && entry_->disk_entry->GetDataSize(kMetadataIndex))
1752 next_state_ = STATE_CACHE_READ_METADATA; 1762 TransitionToState(STATE_CACHE_READ_METADATA);
1753 else 1763 else
1754 next_state_ = STATE_NONE; 1764 TransitionToState(STATE_NONE);
1755 return OK; 1765 return OK;
1756 } 1766 }
1757 1767
1758 if (reading_) { 1768 if (reading_) {
1759 if (network_trans_.get()) { 1769 if (network_trans_.get()) {
1760 next_state_ = STATE_NETWORK_READ; 1770 TransitionToState(STATE_NETWORK_READ);
1761 } else { 1771 } else {
1762 next_state_ = STATE_CACHE_READ_DATA; 1772 TransitionToState(STATE_CACHE_READ_DATA);
1763 } 1773 }
1764 } else if (mode_ != NONE) { 1774 } else if (mode_ != NONE) {
1765 // We are about to return the headers for a byte-range request to the user, 1775 // We are about to return the headers for a byte-range request to the user,
1766 // so let's fix them. 1776 // so let's fix them.
1767 partial_->FixResponseHeaders(response_.headers.get(), true); 1777 partial_->FixResponseHeaders(response_.headers.get(), true);
1768 next_state_ = STATE_NONE; 1778 TransitionToState(STATE_NONE);
1769 } else { 1779 } else {
1770 next_state_ = STATE_NONE; 1780 TransitionToState(STATE_NONE);
1771 } 1781 }
1772 return OK; 1782 return OK;
1773 } 1783 }
1774 1784
1775 int HttpCache::Transaction::DoCacheReadMetadata() { 1785 int HttpCache::Transaction::DoCacheReadMetadata() {
1776 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata"); 1786 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata");
1777 DCHECK(entry_); 1787 DCHECK(entry_);
1778 DCHECK(!response_.metadata.get()); 1788 DCHECK(!response_.metadata.get());
1779 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; 1789 TransitionToState(STATE_CACHE_READ_METADATA_COMPLETE);
1780 1790
1781 response_.metadata = 1791 response_.metadata =
1782 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); 1792 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex));
1783 1793
1784 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO); 1794 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO);
1785 return entry_->disk_entry->ReadData(kMetadataIndex, 0, 1795 return entry_->disk_entry->ReadData(kMetadataIndex, 0,
1786 response_.metadata.get(), 1796 response_.metadata.get(),
1787 response_.metadata->size(), 1797 response_.metadata->size(),
1788 io_callback_); 1798 io_callback_);
1789 } 1799 }
1790 1800
1791 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { 1801 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) {
1792 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadataComplete"); 1802 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadataComplete");
1793 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, 1803 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO,
1794 result); 1804 result);
1795 if (result != response_.metadata->size()) 1805 if (result != response_.metadata->size())
1796 return OnCacheReadError(result, false); 1806 return OnCacheReadError(result, false);
1797 next_state_ = STATE_NONE; 1807 TransitionToState(STATE_NONE);
1798 return OK; 1808 return OK;
1799 } 1809 }
1800 1810
1801 int HttpCache::Transaction::DoNetworkRead() { 1811 int HttpCache::Transaction::DoNetworkRead() {
1802 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); 1812 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead");
1803 next_state_ = STATE_NETWORK_READ_COMPLETE; 1813 TransitionToState(STATE_NETWORK_READ_COMPLETE);
1804 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); 1814 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_);
1805 } 1815 }
1806 1816
1807 int HttpCache::Transaction::DoNetworkReadComplete(int result) { 1817 int HttpCache::Transaction::DoNetworkReadComplete(int result) {
1808 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); 1818 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete");
1809 DCHECK(mode_ & WRITE || mode_ == NONE); 1819 DCHECK(mode_ & WRITE || mode_ == NONE);
1810 1820
1811 if (!cache_.get()) { 1821 if (!cache_.get()) {
1812 next_state_ = STATE_NONE; 1822 TransitionToState(STATE_NONE);
1813 return ERR_UNEXPECTED; 1823 return ERR_UNEXPECTED;
1814 } 1824 }
1815 1825
1816 // If there is an error or we aren't saving the data, we are done; just wait 1826 // If there is an error or we aren't saving the data, we are done; just wait
1817 // until the destructor runs to see if we can keep the data. 1827 // until the destructor runs to see if we can keep the data.
1818 if (mode_ == NONE || result < 0) { 1828 if (mode_ == NONE || result < 0) {
1819 next_state_ = STATE_NONE; 1829 TransitionToState(STATE_NONE);
1820 return result; 1830 return result;
1821 } 1831 }
1822 1832
1823 next_state_ = STATE_CACHE_WRITE_DATA; 1833 TransitionToState(STATE_CACHE_WRITE_DATA);
1824 return result; 1834 return result;
1825 } 1835 }
1826 1836
1827 int HttpCache::Transaction::DoCacheReadData() { 1837 int HttpCache::Transaction::DoCacheReadData() {
1828 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); 1838 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData");
1829 1839
1830 if (request_->method == "HEAD") { 1840 if (request_->method == "HEAD") {
1831 next_state_ = STATE_NONE; 1841 TransitionToState(STATE_NONE);
1832 return 0; 1842 return 0;
1833 } 1843 }
1834 1844
1835 DCHECK(entry_); 1845 DCHECK(entry_);
1836 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; 1846 TransitionToState(STATE_CACHE_READ_DATA_COMPLETE);
1837 1847
1838 if (net_log_.IsCapturing()) 1848 if (net_log_.IsCapturing())
1839 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); 1849 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA);
1840 if (partial_) { 1850 if (partial_) {
1841 return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_, 1851 return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_,
1842 io_callback_); 1852 io_callback_);
1843 } 1853 }
1844 1854
1845 return entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_, 1855 return entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_,
1846 read_buf_.get(), io_buf_len_, 1856 read_buf_.get(), io_buf_len_,
1847 io_callback_); 1857 io_callback_);
1848 } 1858 }
1849 1859
1850 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { 1860 int HttpCache::Transaction::DoCacheReadDataComplete(int result) {
1851 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadDataComplete"); 1861 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadDataComplete");
1852 if (net_log_.IsCapturing()) { 1862 if (net_log_.IsCapturing()) {
1853 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_DATA, 1863 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_DATA,
1854 result); 1864 result);
1855 } 1865 }
1856 1866
1857 if (!cache_.get()) { 1867 if (!cache_.get()) {
1858 next_state_ = STATE_NONE; 1868 TransitionToState(STATE_NONE);
1859 return ERR_UNEXPECTED; 1869 return ERR_UNEXPECTED;
1860 } 1870 }
1861 1871
1862 if (partial_) { 1872 if (partial_) {
1863 // Partial requests are confusing to report in histograms because they may 1873 // Partial requests are confusing to report in histograms because they may
1864 // have multiple underlying requests. 1874 // have multiple underlying requests.
1865 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); 1875 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
1866 return DoPartialCacheReadCompleted(result); 1876 return DoPartialCacheReadCompleted(result);
1867 } 1877 }
1868 1878
1869 if (result > 0) { 1879 if (result > 0) {
1870 read_offset_ += result; 1880 read_offset_ += result;
1871 } else if (result == 0) { // End of file. 1881 } else if (result == 0) { // End of file.
1872 RecordHistograms(); 1882 RecordHistograms();
1873 cache_->DoneReadingFromEntry(entry_, this); 1883 cache_->DoneReadingFromEntry(entry_, this);
1874 entry_ = NULL; 1884 entry_ = NULL;
1875 } else { 1885 } else {
1876 return OnCacheReadError(result, false); 1886 return OnCacheReadError(result, false);
1877 } 1887 }
1878 1888
1879 next_state_ = STATE_NONE; 1889 TransitionToState(STATE_NONE);
1880 return result; 1890 return result;
1881 } 1891 }
1882 1892
1883 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { 1893 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) {
1884 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteData"); 1894 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteData");
1885 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; 1895 TransitionToState(STATE_CACHE_WRITE_DATA_COMPLETE);
1886 write_len_ = num_bytes; 1896 write_len_ = num_bytes;
1887 if (entry_) { 1897 if (entry_) {
1888 if (net_log_.IsCapturing()) 1898 if (net_log_.IsCapturing())
1889 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); 1899 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA);
1890 } 1900 }
1891 1901
1892 if (!entry_ || !num_bytes) 1902 if (!entry_ || !num_bytes)
1893 return num_bytes; 1903 return num_bytes;
1894 1904
1895 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); 1905 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1896 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), 1906 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(),
1897 num_bytes, io_callback_); 1907 num_bytes, io_callback_);
1898 } 1908 }
1899 1909
1900 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { 1910 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) {
1901 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); 1911 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete");
1902 if (entry_) { 1912 if (entry_) {
1903 if (net_log_.IsCapturing()) { 1913 if (net_log_.IsCapturing()) {
1904 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, 1914 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA,
1905 result); 1915 result);
1906 } 1916 }
1907 } 1917 }
1908 if (!cache_.get()) { 1918 if (!cache_.get()) {
1909 next_state_ = STATE_NONE; 1919 TransitionToState(STATE_NONE);
1910 return ERR_UNEXPECTED; 1920 return ERR_UNEXPECTED;
1911 } 1921 }
1912 1922
1913 if (result != write_len_) { 1923 if (result != write_len_) {
1914 DLOG(ERROR) << "failed to write response data to cache"; 1924 DLOG(ERROR) << "failed to write response data to cache";
1915 DoneWritingToEntry(false); 1925 DoneWritingToEntry(false);
1916 1926
1917 // We want to ignore errors writing to disk and just keep reading from 1927 // We want to ignore errors writing to disk and just keep reading from
1918 // the network. 1928 // the network.
1919 result = write_len_; 1929 result = write_len_;
(...skipping 14 matching lines...) Expand all
1934 1944
1935 if (result == 0) { 1945 if (result == 0) {
1936 // End of file. This may be the result of a connection problem so see if we 1946 // End of file. This may be the result of a connection problem so see if we
1937 // have to keep the entry around to be flagged as truncated later on. 1947 // have to keep the entry around to be flagged as truncated later on.
1938 if (done_reading_ || !entry_ || partial_ || 1948 if (done_reading_ || !entry_ || partial_ ||
1939 response_.headers->GetContentLength() <= 0) { 1949 response_.headers->GetContentLength() <= 0) {
1940 DoneWritingToEntry(true); 1950 DoneWritingToEntry(true);
1941 } 1951 }
1942 } 1952 }
1943 1953
1944 next_state_ = STATE_NONE; 1954 TransitionToState(STATE_NONE);
1945 return result; 1955 return result;
1946 } 1956 }
1947 1957
1948 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { 1958 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() {
1949 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); 1959 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse");
1950 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; 1960 TransitionToState(STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE);
1951 return WriteResponseInfoToEntry(true); 1961 return WriteResponseInfoToEntry(true);
1952 } 1962 }
1953 1963
1954 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { 1964 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) {
1955 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); 1965 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse");
1956 1966
1957 next_state_ = STATE_NONE; 1967 TransitionToState(STATE_NONE);
1958 return OnWriteResponseInfoToEntryComplete(result); 1968 return OnWriteResponseInfoToEntryComplete(result);
1959 } 1969 }
1960 1970
1961 //----------------------------------------------------------------------------- 1971 //-----------------------------------------------------------------------------
1962 1972
1963 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, 1973 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log,
1964 const HttpRequestInfo* request) { 1974 const HttpRequestInfo* request) {
1965 net_log_ = net_log; 1975 net_log_ = net_log;
1966 request_ = request; 1976 request_ = request;
1967 effective_load_flags_ = request_->load_flags; 1977 effective_load_flags_ = request_->load_flags;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2084 return false; 2094 return false;
2085 2095
2086 return true; 2096 return true;
2087 } 2097 }
2088 2098
2089 int HttpCache::Transaction::BeginCacheRead() { 2099 int HttpCache::Transaction::BeginCacheRead() {
2090 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. 2100 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges.
2091 // TODO(jkarlin): Either handle this case or DCHECK. 2101 // TODO(jkarlin): Either handle this case or DCHECK.
2092 if (response_.headers->response_code() == 206 || partial_) { 2102 if (response_.headers->response_code() == 206 || partial_) {
2093 NOTREACHED(); 2103 NOTREACHED();
2094 next_state_ = STATE_NONE; 2104 TransitionToState(STATE_NONE);
2095 return ERR_CACHE_MISS; 2105 return ERR_CACHE_MISS;
2096 } 2106 }
2097 2107
2098 // We don't have the whole resource. 2108 // We don't have the whole resource.
2099 if (truncated_) { 2109 if (truncated_) {
2100 next_state_ = STATE_NONE; 2110 TransitionToState(STATE_NONE);
2101 return ERR_CACHE_MISS; 2111 return ERR_CACHE_MISS;
2102 } 2112 }
2103 2113
2104 if (RequiresValidation() != VALIDATION_NONE) { 2114 if (RequiresValidation() != VALIDATION_NONE) {
2105 next_state_ = STATE_NONE; 2115 TransitionToState(STATE_NONE);
2106 return ERR_CACHE_MISS; 2116 return ERR_CACHE_MISS;
2107 } 2117 }
2108 2118
2109 if (request_->method == "HEAD") 2119 if (request_->method == "HEAD")
2110 FixHeadersForHead(); 2120 FixHeadersForHead();
2111 2121
2112 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) 2122 if (entry_->disk_entry->GetDataSize(kMetadataIndex))
2113 next_state_ = STATE_CACHE_READ_METADATA; 2123 TransitionToState(STATE_CACHE_READ_METADATA);
2114 else 2124 else
2115 next_state_ = STATE_NONE; 2125 TransitionToState(STATE_NONE);
2116 2126
2117 return OK; 2127 return OK;
2118 } 2128 }
2119 2129
2120 int HttpCache::Transaction::BeginCacheValidation() { 2130 int HttpCache::Transaction::BeginCacheValidation() {
2121 DCHECK_EQ(mode_, READ_WRITE); 2131 DCHECK_EQ(mode_, READ_WRITE);
2122 2132
2123 ValidationType required_validation = RequiresValidation(); 2133 ValidationType required_validation = RequiresValidation();
2124 2134
2125 bool skip_validation = (required_validation == VALIDATION_NONE); 2135 bool skip_validation = (required_validation == VALIDATION_NONE);
2126 2136
2127 if ((effective_load_flags_ & LOAD_SUPPORT_ASYNC_REVALIDATION) && 2137 if ((effective_load_flags_ & LOAD_SUPPORT_ASYNC_REVALIDATION) &&
2128 required_validation == VALIDATION_ASYNCHRONOUS) { 2138 required_validation == VALIDATION_ASYNCHRONOUS) {
2129 DCHECK_EQ(request_->method, "GET"); 2139 DCHECK_EQ(request_->method, "GET");
2130 skip_validation = true; 2140 skip_validation = true;
2131 response_.async_revalidation_required = true; 2141 response_.async_revalidation_required = true;
2132 } 2142 }
2133 2143
2134 if (request_->method == "HEAD" && 2144 if (request_->method == "HEAD" &&
2135 (truncated_ || response_.headers->response_code() == 206)) { 2145 (truncated_ || response_.headers->response_code() == 206)) {
2136 DCHECK(!partial_); 2146 DCHECK(!partial_);
2137 if (skip_validation) 2147 if (skip_validation)
2138 return SetupEntryForRead(); 2148 return SetupEntryForRead();
2139 2149
2140 // Bail out! 2150 // Bail out!
2141 next_state_ = STATE_SEND_REQUEST; 2151 TransitionToState(STATE_SEND_REQUEST);
2142 mode_ = NONE; 2152 mode_ = NONE;
2143 return OK; 2153 return OK;
2144 } 2154 }
2145 2155
2146 if (truncated_) { 2156 if (truncated_) {
2147 // Truncated entries can cause partial gets, so we shouldn't record this 2157 // Truncated entries can cause partial gets, so we shouldn't record this
2148 // load in histograms. 2158 // load in histograms.
2149 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); 2159 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
2150 skip_validation = !partial_->initial_validation(); 2160 skip_validation = !partial_->initial_validation();
2151 } 2161 }
(...skipping 17 matching lines...) Expand all
2169 // know we won't be falling back to using the cache entry in the 2179 // know we won't be falling back to using the cache entry in the
2170 // LOAD_FROM_CACHE_IF_OFFLINE case. 2180 // LOAD_FROM_CACHE_IF_OFFLINE case.
2171 if (!ConditionalizeRequest()) { 2181 if (!ConditionalizeRequest()) {
2172 couldnt_conditionalize_request_ = true; 2182 couldnt_conditionalize_request_ = true;
2173 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); 2183 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE);
2174 if (partial_) 2184 if (partial_)
2175 return DoRestartPartialRequest(); 2185 return DoRestartPartialRequest();
2176 2186
2177 DCHECK_NE(206, response_.headers->response_code()); 2187 DCHECK_NE(206, response_.headers->response_code());
2178 } 2188 }
2179 next_state_ = STATE_SEND_REQUEST; 2189 TransitionToState(STATE_SEND_REQUEST);
2180 } 2190 }
2181 return OK; 2191 return OK;
2182 } 2192 }
2183 2193
2184 int HttpCache::Transaction::BeginPartialCacheValidation() { 2194 int HttpCache::Transaction::BeginPartialCacheValidation() {
2185 DCHECK_EQ(mode_, READ_WRITE); 2195 DCHECK_EQ(mode_, READ_WRITE);
2186 2196
2187 if (response_.headers->response_code() != 206 && !partial_ && !truncated_) 2197 if (response_.headers->response_code() != 206 && !partial_ && !truncated_)
2188 return BeginCacheValidation(); 2198 return BeginCacheValidation();
2189 2199
2190 // Partial requests should not be recorded in histograms. 2200 // Partial requests should not be recorded in histograms.
2191 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); 2201 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
2192 if (request_->method == "HEAD") 2202 if (request_->method == "HEAD")
2193 return BeginCacheValidation(); 2203 return BeginCacheValidation();
2194 2204
2195 if (!range_requested_) { 2205 if (!range_requested_) {
2196 // The request is not for a range, but we have stored just ranges. 2206 // The request is not for a range, but we have stored just ranges.
2197 2207
2198 partial_.reset(new PartialData()); 2208 partial_.reset(new PartialData());
2199 partial_->SetHeaders(request_->extra_headers); 2209 partial_->SetHeaders(request_->extra_headers);
2200 if (!custom_request_.get()) { 2210 if (!custom_request_.get()) {
2201 custom_request_.reset(new HttpRequestInfo(*request_)); 2211 custom_request_.reset(new HttpRequestInfo(*request_));
2202 request_ = custom_request_.get(); 2212 request_ = custom_request_.get();
2203 } 2213 }
2204 } 2214 }
2205 2215
2206 next_state_ = STATE_CACHE_QUERY_DATA; 2216 TransitionToState(STATE_CACHE_QUERY_DATA);
2207 return OK; 2217 return OK;
2208 } 2218 }
2209 2219
2210 // This should only be called once per request. 2220 // This should only be called once per request.
2211 int HttpCache::Transaction::ValidateEntryHeadersAndContinue() { 2221 int HttpCache::Transaction::ValidateEntryHeadersAndContinue() {
2212 DCHECK_EQ(mode_, READ_WRITE); 2222 DCHECK_EQ(mode_, READ_WRITE);
2213 2223
2214 if (!partial_->UpdateFromStoredHeaders( 2224 if (!partial_->UpdateFromStoredHeaders(
2215 response_.headers.get(), entry_->disk_entry, truncated_)) { 2225 response_.headers.get(), entry_->disk_entry, truncated_)) {
2216 return DoRestartPartialRequest(); 2226 return DoRestartPartialRequest();
2217 } 2227 }
2218 2228
2219 if (response_.headers->response_code() == 206) 2229 if (response_.headers->response_code() == 206)
2220 is_sparse_ = true; 2230 is_sparse_ = true;
2221 2231
2222 if (!partial_->IsRequestedRangeOK()) { 2232 if (!partial_->IsRequestedRangeOK()) {
2223 // The stored data is fine, but the request may be invalid. 2233 // The stored data is fine, but the request may be invalid.
2224 invalid_range_ = true; 2234 invalid_range_ = true;
2225 } 2235 }
2226 2236
2227 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; 2237 TransitionToState(STATE_START_PARTIAL_CACHE_VALIDATION);
2228 return OK; 2238 return OK;
2229 } 2239 }
2230 2240
2231 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() { 2241 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() {
2232 DCHECK_EQ(UPDATE, mode_); 2242 DCHECK_EQ(UPDATE, mode_);
2233 DCHECK(external_validation_.initialized); 2243 DCHECK(external_validation_.initialized);
2234 2244
2235 for (size_t i = 0; i < arraysize(kValidationHeaders); i++) { 2245 for (size_t i = 0; i < arraysize(kValidationHeaders); i++) {
2236 if (external_validation_.values[i].empty()) 2246 if (external_validation_.values[i].empty())
2237 continue; 2247 continue;
(...skipping 22 matching lines...) Expand all
2260 type = EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS; 2270 type = EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS;
2261 else if (RequiresValidation() != VALIDATION_NONE) 2271 else if (RequiresValidation() != VALIDATION_NONE)
2262 type = EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION; 2272 type = EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION;
2263 2273
2264 // TODO(ricea): Add CACHE_USABLE_STALE once stale-while-revalidate CL landed. 2274 // TODO(ricea): Add CACHE_USABLE_STALE once stale-while-revalidate CL landed.
2265 // TODO(ricea): Either remove this histogram or make it permanent by M40. 2275 // TODO(ricea): Either remove this histogram or make it permanent by M40.
2266 UMA_HISTOGRAM_ENUMERATION("HttpCache.ExternallyConditionalized", 2276 UMA_HISTOGRAM_ENUMERATION("HttpCache.ExternallyConditionalized",
2267 type, 2277 type,
2268 EXTERNALLY_CONDITIONALIZED_MAX); 2278 EXTERNALLY_CONDITIONALIZED_MAX);
2269 2279
2270 next_state_ = STATE_SEND_REQUEST; 2280 TransitionToState(STATE_SEND_REQUEST);
2271 return OK; 2281 return OK;
2272 } 2282 }
2273 2283
2274 int HttpCache::Transaction::RestartNetworkRequest() { 2284 int HttpCache::Transaction::RestartNetworkRequest() {
2275 DCHECK(mode_ & WRITE || mode_ == NONE); 2285 DCHECK(mode_ & WRITE || mode_ == NONE);
2276 DCHECK(network_trans_.get()); 2286 DCHECK(network_trans_.get());
2277 DCHECK_EQ(STATE_NONE, next_state_); 2287 DCHECK_EQ(STATE_NONE, next_state_);
2278 2288
2279 next_state_ = STATE_SEND_REQUEST_COMPLETE; 2289 next_state_ = STATE_SEND_REQUEST_COMPLETE;
2280 int rv = network_trans_->RestartIgnoringLastError(io_callback_); 2290 int rv = network_trans_->RestartIgnoringLastError(io_callback_);
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
2612 } 2622 }
2613 } 2623 }
2614 2624
2615 int HttpCache::Transaction::SetupEntryForRead() { 2625 int HttpCache::Transaction::SetupEntryForRead() {
2616 if (network_trans_) 2626 if (network_trans_)
2617 ResetNetworkTransaction(); 2627 ResetNetworkTransaction();
2618 if (partial_) { 2628 if (partial_) {
2619 if (truncated_ || is_sparse_ || !invalid_range_) { 2629 if (truncated_ || is_sparse_ || !invalid_range_) {
2620 // We are going to return the saved response headers to the caller, so 2630 // We are going to return the saved response headers to the caller, so
2621 // we may need to adjust them first. 2631 // we may need to adjust them first.
2622 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; 2632 TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED);
2623 return OK; 2633 return OK;
2624 } else { 2634 } else {
2625 partial_.reset(); 2635 partial_.reset();
2626 } 2636 }
2627 } 2637 }
2628 cache_->ConvertWriterToReader(entry_); 2638 cache_->ConvertWriterToReader(entry_);
2629 mode_ = READ; 2639 mode_ = READ;
2630 2640
2631 if (request_->method == "HEAD") 2641 if (request_->method == "HEAD")
2632 FixHeadersForHead(); 2642 FixHeadersForHead();
2633 2643
2634 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) 2644 if (entry_->disk_entry->GetDataSize(kMetadataIndex))
2635 next_state_ = STATE_CACHE_READ_METADATA; 2645 TransitionToState(STATE_CACHE_READ_METADATA);
2636 else 2646 else
2637 next_state_ = STATE_NONE; 2647 TransitionToState(STATE_NONE);
2638 return OK; 2648 return OK;
2639 } 2649 }
2640 2650
2641 int HttpCache::Transaction::WriteToEntry(int index, int offset, 2651 int HttpCache::Transaction::WriteToEntry(int index, int offset,
2642 IOBuffer* data, int data_len, 2652 IOBuffer* data, int data_len,
2643 const CompletionCallback& callback) { 2653 const CompletionCallback& callback) {
2644 if (!entry_) 2654 if (!entry_)
2645 return data_len; 2655 return data_len;
2646 2656
2647 int rv = 0; 2657 int rv = 0;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2733 if (cache_.get()) 2743 if (cache_.get())
2734 cache_->DoomActiveEntry(cache_key_); 2744 cache_->DoomActiveEntry(cache_key_);
2735 2745
2736 if (restart) { 2746 if (restart) {
2737 DCHECK(!reading_); 2747 DCHECK(!reading_);
2738 DCHECK(!network_trans_.get()); 2748 DCHECK(!network_trans_.get());
2739 cache_->DoneWithEntry(entry_, this, false); 2749 cache_->DoneWithEntry(entry_, this, false);
2740 entry_ = NULL; 2750 entry_ = NULL;
2741 is_sparse_ = false; 2751 is_sparse_ = false;
2742 partial_.reset(); 2752 partial_.reset();
2743 next_state_ = STATE_GET_BACKEND; 2753 TransitionToState(STATE_GET_BACKEND);
2744 return OK; 2754 return OK;
2745 } 2755 }
2746 2756
2747 next_state_ = STATE_NONE; 2757 TransitionToState(STATE_NONE);
2748 return ERR_CACHE_READ_FAILURE; 2758 return ERR_CACHE_READ_FAILURE;
2749 } 2759 }
2750 2760
2751 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { 2761 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) {
2752 if (entry_lock_waiting_since_ != start_time) 2762 if (entry_lock_waiting_since_ != start_time)
2753 return; 2763 return;
2754 2764
2755 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); 2765 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE);
2756 2766
2757 if (!cache_) 2767 if (!cache_)
(...skipping 14 matching lines...) Expand all
2772 if (delete_object) 2782 if (delete_object)
2773 partial_.reset(NULL); 2783 partial_.reset(NULL);
2774 } 2784 }
2775 2785
2776 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { 2786 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) {
2777 partial_->OnNetworkReadCompleted(result); 2787 partial_->OnNetworkReadCompleted(result);
2778 2788
2779 if (result == 0) { 2789 if (result == 0) {
2780 // We need to move on to the next range. 2790 // We need to move on to the next range.
2781 ResetNetworkTransaction(); 2791 ResetNetworkTransaction();
2782 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; 2792 TransitionToState(STATE_START_PARTIAL_CACHE_VALIDATION);
2783 } else { 2793 } else {
2784 next_state_ = STATE_NONE; 2794 TransitionToState(STATE_NONE);
2785 } 2795 }
2786 return result; 2796 return result;
2787 } 2797 }
2788 2798
2789 int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) { 2799 int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) {
2790 partial_->OnCacheReadCompleted(result); 2800 partial_->OnCacheReadCompleted(result);
2791 2801
2792 if (result == 0 && mode_ == READ_WRITE) { 2802 if (result == 0 && mode_ == READ_WRITE) {
2793 // We need to move on to the next range. 2803 // We need to move on to the next range.
2794 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; 2804 TransitionToState(STATE_START_PARTIAL_CACHE_VALIDATION);
2795 } else if (result < 0) { 2805 } else if (result < 0) {
2796 return OnCacheReadError(result, false); 2806 return OnCacheReadError(result, false);
2797 } else { 2807 } else {
2798 next_state_ = STATE_NONE; 2808 TransitionToState(STATE_NONE);
2799 } 2809 }
2800 return result; 2810 return result;
2801 } 2811 }
2802 2812
2803 int HttpCache::Transaction::DoRestartPartialRequest() { 2813 int HttpCache::Transaction::DoRestartPartialRequest() {
2804 // The stored data cannot be used. Get rid of it and restart this request. 2814 // The stored data cannot be used. Get rid of it and restart this request.
2805 net_log_.AddEvent(NetLogEventType::HTTP_CACHE_RESTART_PARTIAL_REQUEST); 2815 net_log_.AddEvent(NetLogEventType::HTTP_CACHE_RESTART_PARTIAL_REQUEST);
2806 2816
2807 // WRITE + Doom + STATE_INIT_ENTRY == STATE_CREATE_ENTRY (without an attempt 2817 // WRITE + Doom + STATE_INIT_ENTRY == STATE_CREATE_ENTRY (without an attempt
2808 // to Doom the entry again). 2818 // to Doom the entry again).
2809 mode_ = WRITE; 2819 mode_ = WRITE;
2810 ResetPartialState(!range_requested_); 2820 ResetPartialState(!range_requested_);
2811 next_state_ = STATE_CREATE_ENTRY; 2821 TransitionToState(STATE_CREATE_ENTRY);
2812 return OK; 2822 return OK;
2813 } 2823 }
2814 2824
2815 void HttpCache::Transaction::ResetPartialState(bool delete_object) { 2825 void HttpCache::Transaction::ResetPartialState(bool delete_object) {
2816 partial_->RestoreHeaders(&custom_request_->extra_headers); 2826 partial_->RestoreHeaders(&custom_request_->extra_headers);
2817 DoomPartialEntry(delete_object); 2827 DoomPartialEntry(delete_object);
2818 2828
2819 if (!delete_object) { 2829 if (!delete_object) {
2820 // The simplest way to re-initialize partial_ is to create a new object. 2830 // The simplest way to re-initialize partial_ is to create a new object.
2821 partial_.reset(new PartialData()); 2831 partial_.reset(new PartialData());
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 } 3076 }
3067 default: 3077 default:
3068 NOTREACHED(); 3078 NOTREACHED();
3069 } 3079 }
3070 } 3080 }
3071 3081
3072 void HttpCache::Transaction::OnIOComplete(int result) { 3082 void HttpCache::Transaction::OnIOComplete(int result) {
3073 DoLoop(result); 3083 DoLoop(result);
3074 } 3084 }
3075 3085
3086 void HttpCache::Transaction::TransitionToState(State state) {
3087 // Ensure that the state is only set once per Do* state.
3088 DCHECK(in_do_loop_);
3089 DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state;
3090 next_state_ = state;
3091 }
3092
3076 } // namespace net 3093 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698