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

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

Powered by Google App Engine
This is Rietveld 408576698