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

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

Issue 1240503002: reoder functions in the order they are normally executed (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments addressed Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_cache_transaction.h" 5 #include "net/http/http_cache_transaction.h"
6 6
7 #include "build/build_config.h" // For OS_POSIX 7 #include "build/build_config.h" // For OS_POSIX
8 8
9 #if defined(OS_POSIX) 9 #if defined(OS_POSIX)
10 #include <unistd.h> 10 #include <unistd.h>
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 State state = next_state_; 797 State state = next_state_;
798 next_state_ = STATE_NONE; 798 next_state_ = STATE_NONE;
799 switch (state) { 799 switch (state) {
800 case STATE_GET_BACKEND: 800 case STATE_GET_BACKEND:
801 DCHECK_EQ(OK, rv); 801 DCHECK_EQ(OK, rv);
802 rv = DoGetBackend(); 802 rv = DoGetBackend();
803 break; 803 break;
804 case STATE_GET_BACKEND_COMPLETE: 804 case STATE_GET_BACKEND_COMPLETE:
805 rv = DoGetBackendComplete(rv); 805 rv = DoGetBackendComplete(rv);
806 break; 806 break;
807 case STATE_SEND_REQUEST:
808 DCHECK_EQ(OK, rv);
809 rv = DoSendRequest();
810 break;
811 case STATE_SEND_REQUEST_COMPLETE:
812 rv = DoSendRequestComplete(rv);
813 break;
814 case STATE_SUCCESSFUL_SEND_REQUEST:
815 DCHECK_EQ(OK, rv);
816 rv = DoSuccessfulSendRequest();
817 break;
818 case STATE_NETWORK_READ:
819 DCHECK_EQ(OK, rv);
820 rv = DoNetworkRead();
821 break;
822 case STATE_NETWORK_READ_COMPLETE:
823 rv = DoNetworkReadComplete(rv);
824 break;
825 case STATE_INIT_ENTRY: 807 case STATE_INIT_ENTRY:
826 DCHECK_EQ(OK, rv); 808 DCHECK_EQ(OK, rv);
827 rv = DoInitEntry(); 809 rv = DoInitEntry();
828 break; 810 break;
829 case STATE_OPEN_ENTRY: 811 case STATE_OPEN_ENTRY:
830 DCHECK_EQ(OK, rv); 812 DCHECK_EQ(OK, rv);
831 rv = DoOpenEntry(); 813 rv = DoOpenEntry();
832 break; 814 break;
833 case STATE_OPEN_ENTRY_COMPLETE: 815 case STATE_OPEN_ENTRY_COMPLETE:
834 rv = DoOpenEntryComplete(rv); 816 rv = DoOpenEntryComplete(rv);
835 break; 817 break;
836 case STATE_CREATE_ENTRY:
837 DCHECK_EQ(OK, rv);
838 rv = DoCreateEntry();
839 break;
840 case STATE_CREATE_ENTRY_COMPLETE:
841 rv = DoCreateEntryComplete(rv);
842 break;
843 case STATE_DOOM_ENTRY: 818 case STATE_DOOM_ENTRY:
844 DCHECK_EQ(OK, rv); 819 DCHECK_EQ(OK, rv);
845 rv = DoDoomEntry(); 820 rv = DoDoomEntry();
846 break; 821 break;
847 case STATE_DOOM_ENTRY_COMPLETE: 822 case STATE_DOOM_ENTRY_COMPLETE:
848 rv = DoDoomEntryComplete(rv); 823 rv = DoDoomEntryComplete(rv);
849 break; 824 break;
825 case STATE_CREATE_ENTRY:
826 DCHECK_EQ(OK, rv);
827 rv = DoCreateEntry();
828 break;
829 case STATE_CREATE_ENTRY_COMPLETE:
830 rv = DoCreateEntryComplete(rv);
831 break;
850 case STATE_ADD_TO_ENTRY: 832 case STATE_ADD_TO_ENTRY:
851 DCHECK_EQ(OK, rv); 833 DCHECK_EQ(OK, rv);
852 rv = DoAddToEntry(); 834 rv = DoAddToEntry();
853 break; 835 break;
854 case STATE_ADD_TO_ENTRY_COMPLETE: 836 case STATE_ADD_TO_ENTRY_COMPLETE:
855 rv = DoAddToEntryComplete(rv); 837 rv = DoAddToEntryComplete(rv);
856 break; 838 break;
839 case STATE_CACHE_READ_RESPONSE:
840 DCHECK_EQ(OK, rv);
841 rv = DoCacheReadResponse();
842 break;
843 case STATE_CACHE_READ_RESPONSE_COMPLETE:
844 rv = DoCacheReadResponseComplete(rv);
845 break;
846 case STATE_TOGGLE_UNUSED_SINCE_PREFETCH:
847 DCHECK_EQ(OK, rv);
848 rv = DoCacheToggleUnusedSincePrefetch();
849 break;
850 case STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE:
851 rv = DoCacheToggleUnusedSincePrefetchComplete(rv);
852 break;
853 case STATE_CACHE_DISPATCH_VALIDATION:
854 DCHECK_EQ(OK, rv);
855 rv = DoCacheDispatchValidation();
856 break;
857 case STATE_CACHE_QUERY_DATA:
858 DCHECK_EQ(OK, rv);
859 rv = DoCacheQueryData();
860 break;
861 case STATE_CACHE_QUERY_DATA_COMPLETE:
862 rv = DoCacheQueryDataComplete(rv);
863 break;
857 case STATE_START_PARTIAL_CACHE_VALIDATION: 864 case STATE_START_PARTIAL_CACHE_VALIDATION:
858 DCHECK_EQ(OK, rv); 865 DCHECK_EQ(OK, rv);
859 rv = DoStartPartialCacheValidation(); 866 rv = DoStartPartialCacheValidation();
860 break; 867 break;
861 case STATE_COMPLETE_PARTIAL_CACHE_VALIDATION: 868 case STATE_COMPLETE_PARTIAL_CACHE_VALIDATION:
862 rv = DoCompletePartialCacheValidation(rv); 869 rv = DoCompletePartialCacheValidation(rv);
863 break; 870 break;
871 case STATE_SEND_REQUEST:
872 DCHECK_EQ(OK, rv);
873 rv = DoSendRequest();
874 break;
875 case STATE_SEND_REQUEST_COMPLETE:
876 rv = DoSendRequestComplete(rv);
877 break;
878 case STATE_SUCCESSFUL_SEND_REQUEST:
879 DCHECK_EQ(OK, rv);
880 rv = DoSuccessfulSendRequest();
881 break;
864 case STATE_UPDATE_CACHED_RESPONSE: 882 case STATE_UPDATE_CACHED_RESPONSE:
865 DCHECK_EQ(OK, rv); 883 DCHECK_EQ(OK, rv);
866 rv = DoUpdateCachedResponse(); 884 rv = DoUpdateCachedResponse();
867 break; 885 break;
868 case STATE_UPDATE_CACHED_RESPONSE_COMPLETE: 886 case STATE_UPDATE_CACHED_RESPONSE_COMPLETE:
869 rv = DoUpdateCachedResponseComplete(rv); 887 rv = DoUpdateCachedResponseComplete(rv);
870 break; 888 break;
871 case STATE_OVERWRITE_CACHED_RESPONSE: 889 case STATE_OVERWRITE_CACHED_RESPONSE:
872 DCHECK_EQ(OK, rv); 890 DCHECK_EQ(OK, rv);
873 rv = DoOverwriteCachedResponse(); 891 rv = DoOverwriteCachedResponse();
874 break; 892 break;
893 case STATE_CACHE_WRITE_RESPONSE:
894 DCHECK_EQ(OK, rv);
895 rv = DoCacheWriteResponse();
896 break;
897 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE:
898 DCHECK_EQ(OK, rv);
899 rv = DoCacheWriteTruncatedResponse();
900 break;
901 case STATE_CACHE_WRITE_RESPONSE_COMPLETE:
902 rv = DoCacheWriteResponseComplete(rv);
903 break;
875 case STATE_TRUNCATE_CACHED_DATA: 904 case STATE_TRUNCATE_CACHED_DATA:
876 DCHECK_EQ(OK, rv); 905 DCHECK_EQ(OK, rv);
877 rv = DoTruncateCachedData(); 906 rv = DoTruncateCachedData();
878 break; 907 break;
879 case STATE_TRUNCATE_CACHED_DATA_COMPLETE: 908 case STATE_TRUNCATE_CACHED_DATA_COMPLETE:
880 rv = DoTruncateCachedDataComplete(rv); 909 rv = DoTruncateCachedDataComplete(rv);
881 break; 910 break;
882 case STATE_TRUNCATE_CACHED_METADATA: 911 case STATE_TRUNCATE_CACHED_METADATA:
883 DCHECK_EQ(OK, rv); 912 DCHECK_EQ(OK, rv);
884 rv = DoTruncateCachedMetadata(); 913 rv = DoTruncateCachedMetadata();
885 break; 914 break;
886 case STATE_TRUNCATE_CACHED_METADATA_COMPLETE: 915 case STATE_TRUNCATE_CACHED_METADATA_COMPLETE:
887 rv = DoTruncateCachedMetadataComplete(rv); 916 rv = DoTruncateCachedMetadataComplete(rv);
888 break; 917 break;
889 case STATE_PARTIAL_HEADERS_RECEIVED: 918 case STATE_PARTIAL_HEADERS_RECEIVED:
890 DCHECK_EQ(OK, rv); 919 DCHECK_EQ(OK, rv);
891 rv = DoPartialHeadersReceived(); 920 rv = DoPartialHeadersReceived();
892 break; 921 break;
893 case STATE_CACHE_READ_RESPONSE:
894 DCHECK_EQ(OK, rv);
895 rv = DoCacheReadResponse();
896 break;
897 case STATE_CACHE_READ_RESPONSE_COMPLETE:
898 rv = DoCacheReadResponseComplete(rv);
899 break;
900 case STATE_CACHE_DISPATCH_VALIDATION:
901 DCHECK_EQ(OK, rv);
902 rv = DoCacheDispatchValidation();
903 break;
904 case STATE_TOGGLE_UNUSED_SINCE_PREFETCH:
905 DCHECK_EQ(OK, rv);
906 rv = DoCacheToggleUnusedSincePrefetch();
907 break;
908 case STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE:
909 rv = DoCacheToggleUnusedSincePrefetchComplete(rv);
910 break;
911 case STATE_CACHE_WRITE_RESPONSE:
912 DCHECK_EQ(OK, rv);
913 rv = DoCacheWriteResponse();
914 break;
915 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE:
916 DCHECK_EQ(OK, rv);
917 rv = DoCacheWriteTruncatedResponse();
918 break;
919 case STATE_CACHE_WRITE_RESPONSE_COMPLETE:
920 rv = DoCacheWriteResponseComplete(rv);
921 break;
922 case STATE_CACHE_READ_METADATA: 922 case STATE_CACHE_READ_METADATA:
923 DCHECK_EQ(OK, rv); 923 DCHECK_EQ(OK, rv);
924 rv = DoCacheReadMetadata(); 924 rv = DoCacheReadMetadata();
925 break; 925 break;
926 case STATE_CACHE_READ_METADATA_COMPLETE: 926 case STATE_CACHE_READ_METADATA_COMPLETE:
927 rv = DoCacheReadMetadataComplete(rv); 927 rv = DoCacheReadMetadataComplete(rv);
928 break; 928 break;
929 case STATE_CACHE_QUERY_DATA: 929 case STATE_NETWORK_READ:
930 DCHECK_EQ(OK, rv); 930 DCHECK_EQ(OK, rv);
931 rv = DoCacheQueryData(); 931 rv = DoNetworkRead();
932 break; 932 break;
933 case STATE_CACHE_QUERY_DATA_COMPLETE: 933 case STATE_NETWORK_READ_COMPLETE:
934 rv = DoCacheQueryDataComplete(rv); 934 rv = DoNetworkReadComplete(rv);
935 break; 935 break;
936 case STATE_CACHE_READ_DATA: 936 case STATE_CACHE_READ_DATA:
937 DCHECK_EQ(OK, rv); 937 DCHECK_EQ(OK, rv);
938 rv = DoCacheReadData(); 938 rv = DoCacheReadData();
939 break; 939 break;
940 case STATE_CACHE_READ_DATA_COMPLETE: 940 case STATE_CACHE_READ_DATA_COMPLETE:
941 rv = DoCacheReadDataComplete(rv); 941 rv = DoCacheReadDataComplete(rv);
942 break; 942 break;
943 case STATE_CACHE_WRITE_DATA: 943 case STATE_CACHE_WRITE_DATA:
944 rv = DoCacheWriteData(rv); 944 rv = DoCacheWriteData(rv);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 } else { 1024 } else {
1025 next_state_ = STATE_INIT_ENTRY; 1025 next_state_ = STATE_INIT_ENTRY;
1026 } 1026 }
1027 1027
1028 // This is only set if we have something to do with the response. 1028 // This is only set if we have something to do with the response.
1029 range_requested_ = (partial_.get() != NULL); 1029 range_requested_ = (partial_.get() != NULL);
1030 1030
1031 return OK; 1031 return OK;
1032 } 1032 }
1033 1033
1034 int HttpCache::Transaction::DoSendRequest() {
1035 DCHECK(mode_ & WRITE || mode_ == NONE);
1036 DCHECK(!network_trans_.get());
1037
1038 send_request_since_ = TimeTicks::Now();
1039
1040 // Create a network transaction.
1041 int rv = cache_->network_layer_->CreateTransaction(priority_,
1042 &network_trans_);
1043 if (rv != OK)
1044 return rv;
1045 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_);
1046 network_trans_->SetBeforeProxyHeadersSentCallback(
1047 before_proxy_headers_sent_callback_);
1048
1049 // Old load timing information, if any, is now obsolete.
1050 old_network_trans_load_timing_.reset();
1051
1052 if (websocket_handshake_stream_base_create_helper_)
1053 network_trans_->SetWebSocketHandshakeStreamCreateHelper(
1054 websocket_handshake_stream_base_create_helper_);
1055
1056 next_state_ = STATE_SEND_REQUEST_COMPLETE;
1057 rv = network_trans_->Start(request_, io_callback_, net_log_);
1058 return rv;
1059 }
1060
1061 int HttpCache::Transaction::DoSendRequestComplete(int result) {
1062 if (!cache_.get())
1063 return ERR_UNEXPECTED;
1064
1065 // If we tried to conditionalize the request and failed, we know
1066 // we won't be reading from the cache after this point.
1067 if (couldnt_conditionalize_request_)
1068 mode_ = WRITE;
1069
1070 if (result == OK) {
1071 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST;
1072 return OK;
1073 }
1074
1075 const HttpResponseInfo* response = network_trans_->GetResponseInfo();
1076 response_.network_accessed = response->network_accessed;
1077
1078 // Do not record requests that have network errors or restarts.
1079 UpdateTransactionPattern(PATTERN_NOT_COVERED);
1080 if (IsCertificateError(result)) {
1081 // If we get a certificate error, then there is a certificate in ssl_info,
1082 // so GetResponseInfo() should never return NULL here.
1083 DCHECK(response);
1084 response_.ssl_info = response->ssl_info;
1085 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
1086 DCHECK(response);
1087 response_.cert_request_info = response->cert_request_info;
1088 } else if (response_.was_cached) {
1089 DoneWritingToEntry(true);
1090 }
1091
1092 return result;
1093 }
1094
1095 // We received the response headers and there is no error.
1096 int HttpCache::Transaction::DoSuccessfulSendRequest() {
1097 DCHECK(!new_response_);
1098 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo();
1099
1100 if (new_response->headers->response_code() == 401 ||
1101 new_response->headers->response_code() == 407) {
1102 auth_response_ = *new_response;
1103 if (!reading_)
1104 return OK;
1105
1106 // We initiated a second request the caller doesn't know about. We should be
1107 // able to authenticate this request because we should have authenticated
1108 // this URL moments ago.
1109 if (IsReadyToRestartForAuth()) {
1110 DCHECK(!response_.auth_challenge.get());
1111 next_state_ = STATE_SEND_REQUEST_COMPLETE;
1112 // In theory we should check to see if there are new cookies, but there
1113 // is no way to do that from here.
1114 return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_);
1115 }
1116
1117 // We have to perform cleanup at this point so that at least the next
1118 // request can succeed. We do not retry at this point, because data
1119 // has been read and we have no way to gather credentials. We would
1120 // fail again, and potentially loop. This can happen if the credentials
1121 // expire while chrome is suspended.
1122 if (entry_)
1123 DoomPartialEntry(false);
1124 mode_ = NONE;
1125 partial_.reset();
1126 ResetNetworkTransaction();
1127 return ERR_CACHE_AUTH_FAILURE_AFTER_READ;
1128 }
1129
1130 new_response_ = new_response;
1131 if (!ValidatePartialResponse() && !auth_response_.headers.get()) {
1132 // Something went wrong with this request and we have to restart it.
1133 // If we have an authentication response, we are exposed to weird things
1134 // hapenning if the user cancels the authentication before we receive
1135 // the new response.
1136 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST);
1137 UpdateTransactionPattern(PATTERN_NOT_COVERED);
1138 response_ = HttpResponseInfo();
1139 ResetNetworkTransaction();
1140 new_response_ = NULL;
1141 next_state_ = STATE_SEND_REQUEST;
1142 return OK;
1143 }
1144
1145 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) {
1146 // We have stored the full entry, but it changed and the server is
1147 // sending a range. We have to delete the old entry.
1148 UpdateTransactionPattern(PATTERN_NOT_COVERED);
1149 DoneWritingToEntry(false);
1150 }
1151
1152 if (mode_ == WRITE &&
1153 transaction_pattern_ != PATTERN_ENTRY_CANT_CONDITIONALIZE) {
1154 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED);
1155 }
1156
1157 // Invalidate any cached GET with a successful PUT or DELETE.
1158 if (mode_ == WRITE &&
1159 (request_->method == "PUT" || request_->method == "DELETE")) {
1160 if (NonErrorResponse(new_response->headers->response_code())) {
1161 int ret = cache_->DoomEntry(cache_key_, NULL);
1162 DCHECK_EQ(OK, ret);
1163 }
1164 cache_->DoneWritingToEntry(entry_, true);
1165 entry_ = NULL;
1166 mode_ = NONE;
1167 }
1168
1169 // Invalidate any cached GET with a successful POST.
1170 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) &&
1171 request_->method == "POST" &&
1172 NonErrorResponse(new_response->headers->response_code())) {
1173 cache_->DoomMainEntryForUrl(request_->url);
1174 }
1175
1176 RecordNoStoreHeaderHistogram(request_->load_flags, new_response);
1177
1178 if (new_response_->headers->response_code() == 416 &&
1179 (request_->method == "GET" || request_->method == "POST")) {
1180 // If there is an active entry it may be destroyed with this transaction.
1181 response_ = *new_response_;
1182 return OK;
1183 }
1184
1185 // Are we expecting a response to a conditional query?
1186 if (mode_ == READ_WRITE || mode_ == UPDATE) {
1187 if (new_response->headers->response_code() == 304 || handling_206_) {
1188 UpdateTransactionPattern(PATTERN_ENTRY_VALIDATED);
1189 next_state_ = STATE_UPDATE_CACHED_RESPONSE;
1190 return OK;
1191 }
1192 UpdateTransactionPattern(PATTERN_ENTRY_UPDATED);
1193 mode_ = WRITE;
1194 }
1195
1196 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE;
1197 return OK;
1198 }
1199
1200 int HttpCache::Transaction::DoNetworkRead() {
1201 next_state_ = STATE_NETWORK_READ_COMPLETE;
1202 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_);
1203 }
1204
1205 int HttpCache::Transaction::DoNetworkReadComplete(int result) {
1206 DCHECK(mode_ & WRITE || mode_ == NONE);
1207
1208 if (!cache_.get())
1209 return ERR_UNEXPECTED;
1210
1211 // If there is an error or we aren't saving the data, we are done; just wait
1212 // until the destructor runs to see if we can keep the data.
1213 if (mode_ == NONE || result < 0)
1214 return result;
1215
1216 next_state_ = STATE_CACHE_WRITE_DATA;
1217 return result;
1218 }
1219
1220 int HttpCache::Transaction::DoInitEntry() { 1034 int HttpCache::Transaction::DoInitEntry() {
1221 DCHECK(!new_entry_); 1035 DCHECK(!new_entry_);
1222 1036
1223 if (!cache_.get()) 1037 if (!cache_.get())
1224 return ERR_UNEXPECTED; 1038 return ERR_UNEXPECTED;
1225 1039
1226 if (mode_ == WRITE) { 1040 if (mode_ == WRITE) {
1227 next_state_ = STATE_DOOM_ENTRY; 1041 next_state_ = STATE_DOOM_ENTRY;
1228 return OK; 1042 return OK;
1229 } 1043 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 mode_ = NONE; 1089 mode_ = NONE;
1276 next_state_ = STATE_SEND_REQUEST; 1090 next_state_ = STATE_SEND_REQUEST;
1277 return OK; 1091 return OK;
1278 } 1092 }
1279 1093
1280 // The entry does not exist, and we are not permitted to create a new entry, 1094 // The entry does not exist, and we are not permitted to create a new entry,
1281 // so we must fail. 1095 // so we must fail.
1282 return ERR_CACHE_MISS; 1096 return ERR_CACHE_MISS;
1283 } 1097 }
1284 1098
1099 int HttpCache::Transaction::DoDoomEntry() {
1100 next_state_ = STATE_DOOM_ENTRY_COMPLETE;
1101 cache_pending_ = true;
1102 if (first_cache_access_since_.is_null())
1103 first_cache_access_since_ = TimeTicks::Now();
1104 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY);
1105 return cache_->DoomEntry(cache_key_, this);
1106 }
1107
1108 int HttpCache::Transaction::DoDoomEntryComplete(int result) {
1109 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY, result);
1110 next_state_ = STATE_CREATE_ENTRY;
1111 cache_pending_ = false;
1112 if (result == ERR_CACHE_RACE)
1113 next_state_ = STATE_INIT_ENTRY;
1114 return OK;
1115 }
1116
1285 int HttpCache::Transaction::DoCreateEntry() { 1117 int HttpCache::Transaction::DoCreateEntry() {
1286 DCHECK(!new_entry_); 1118 DCHECK(!new_entry_);
1287 next_state_ = STATE_CREATE_ENTRY_COMPLETE; 1119 next_state_ = STATE_CREATE_ENTRY_COMPLETE;
1288 cache_pending_ = true; 1120 cache_pending_ = true;
1289 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY); 1121 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY);
1290 return cache_->CreateEntry(cache_key_, &new_entry_, this); 1122 return cache_->CreateEntry(cache_key_, &new_entry_, this);
1291 } 1123 }
1292 1124
1293 int HttpCache::Transaction::DoCreateEntryComplete(int result) { 1125 int HttpCache::Transaction::DoCreateEntryComplete(int result) {
1294 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is 1126 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is
(...skipping 16 matching lines...) Expand all
1311 // OpenOrCreate() method exposed by the disk cache. 1143 // OpenOrCreate() method exposed by the disk cache.
1312 DLOG(WARNING) << "Unable to create cache entry"; 1144 DLOG(WARNING) << "Unable to create cache entry";
1313 mode_ = NONE; 1145 mode_ = NONE;
1314 if (partial_.get()) 1146 if (partial_.get())
1315 partial_->RestoreHeaders(&custom_request_->extra_headers); 1147 partial_->RestoreHeaders(&custom_request_->extra_headers);
1316 next_state_ = STATE_SEND_REQUEST; 1148 next_state_ = STATE_SEND_REQUEST;
1317 } 1149 }
1318 return OK; 1150 return OK;
1319 } 1151 }
1320 1152
1321 int HttpCache::Transaction::DoDoomEntry() {
1322 next_state_ = STATE_DOOM_ENTRY_COMPLETE;
1323 cache_pending_ = true;
1324 if (first_cache_access_since_.is_null())
1325 first_cache_access_since_ = TimeTicks::Now();
1326 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY);
1327 return cache_->DoomEntry(cache_key_, this);
1328 }
1329
1330 int HttpCache::Transaction::DoDoomEntryComplete(int result) {
1331 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY, result);
1332 next_state_ = STATE_CREATE_ENTRY;
1333 cache_pending_ = false;
1334 if (result == ERR_CACHE_RACE)
1335 next_state_ = STATE_INIT_ENTRY;
1336 return OK;
1337 }
1338
1339 int HttpCache::Transaction::DoAddToEntry() { 1153 int HttpCache::Transaction::DoAddToEntry() {
1340 DCHECK(new_entry_); 1154 DCHECK(new_entry_);
1341 cache_pending_ = true; 1155 cache_pending_ = true;
1342 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; 1156 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE;
1343 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); 1157 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY);
1344 DCHECK(entry_lock_waiting_since_.is_null()); 1158 DCHECK(entry_lock_waiting_since_.is_null());
1345 entry_lock_waiting_since_ = TimeTicks::Now(); 1159 entry_lock_waiting_since_ = TimeTicks::Now();
1346 int rv = cache_->AddTransactionToEntry(new_entry_, this); 1160 int rv = cache_->AddTransactionToEntry(new_entry_, this);
1347 if (rv == ERR_IO_PENDING) { 1161 if (rv == ERR_IO_PENDING) {
1348 if (bypass_lock_for_test_) { 1162 if (bypass_lock_for_test_) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 partial_->RestoreHeaders(&custom_request_->extra_headers); 1234 partial_->RestoreHeaders(&custom_request_->extra_headers);
1421 next_state_ = STATE_SEND_REQUEST; 1235 next_state_ = STATE_SEND_REQUEST;
1422 } else { 1236 } else {
1423 // We have to read the headers from the cached entry. 1237 // We have to read the headers from the cached entry.
1424 DCHECK(mode_ & READ_META); 1238 DCHECK(mode_ & READ_META);
1425 next_state_ = STATE_CACHE_READ_RESPONSE; 1239 next_state_ = STATE_CACHE_READ_RESPONSE;
1426 } 1240 }
1427 return OK; 1241 return OK;
1428 } 1242 }
1429 1243
1244 int HttpCache::Transaction::DoCacheReadResponse() {
1245 DCHECK(entry_);
1246 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE;
1247
1248 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex);
1249 read_buf_ = new IOBuffer(io_buf_len_);
1250
1251 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO);
1252 return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(),
1253 io_buf_len_, io_callback_);
1254 }
1255
1256 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
1257 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result);
1258 if (result != io_buf_len_ ||
1259 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, &response_,
1260 &truncated_)) {
1261 return OnCacheReadError(result, true);
1262 }
1263
1264 // cert_cache() will be null if the CertCacheTrial field trial is disabled.
1265 if (cache_->cert_cache() && response_.ssl_info.is_valid())
1266 ReadCertChain();
1267
1268 // Some resources may have slipped in as truncated when they're not.
1269 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1270 if (response_.headers->GetContentLength() == current_size)
1271 truncated_ = false;
1272
1273 if ((response_.unused_since_prefetch &&
1274 !(request_->load_flags & LOAD_PREFETCH)) ||
1275 (!response_.unused_since_prefetch &&
1276 (request_->load_flags & LOAD_PREFETCH))) {
1277 // Either this is the first use of an entry since it was prefetched or
1278 // this is a prefetch. The value of response.unused_since_prefetch is valid
1279 // for this transaction but the bit needs to be flipped in storage.
1280 next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH;
1281 return OK;
1282 }
1283
1284 next_state_ = STATE_CACHE_DISPATCH_VALIDATION;
1285 return OK;
1286 }
1287
1288 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch() {
1289 // Write back the toggled value for the next use of this entry.
1290 response_.unused_since_prefetch = !response_.unused_since_prefetch;
1291
1292 // TODO(jkarlin): If DoUpdateCachedResponse is also called for this
1293 // transaction then metadata will be written to cache twice. If prefetching
1294 // becomes more common, consider combining the writes.
1295 target_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE;
1296 next_state_ = STATE_CACHE_WRITE_RESPONSE;
1297 return OK;
1298 }
1299
1300 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetchComplete(
1301 int result) {
1302 // Restore the original value for this transaction.
1303 response_.unused_since_prefetch = !response_.unused_since_prefetch;
1304 next_state_ = STATE_CACHE_DISPATCH_VALIDATION;
1305 return OK;
1306 }
1307
1308 int HttpCache::Transaction::DoCacheDispatchValidation() {
1309 // We now have access to the cache entry.
1310 //
1311 // o if we are a reader for the transaction, then we can start reading the
1312 // cache entry.
1313 //
1314 // o if we can read or write, then we should check if the cache entry needs
1315 // to be validated and then issue a network request if needed or just read
1316 // from the cache if the cache entry is already valid.
1317 //
1318 // o if we are set to UPDATE, then we are handling an externally
1319 // conditionalized request (if-modified-since / if-none-match). We check
1320 // if the request headers define a validation request.
1321 //
1322 int result = ERR_FAILED;
1323 switch (mode_) {
1324 case READ:
1325 UpdateTransactionPattern(PATTERN_ENTRY_USED);
1326 result = BeginCacheRead();
1327 break;
1328 case READ_WRITE:
1329 result = BeginPartialCacheValidation();
1330 break;
1331 case UPDATE:
1332 result = BeginExternallyConditionalizedRequest();
1333 break;
1334 case WRITE:
1335 default:
1336 NOTREACHED();
1337 }
1338 return result;
1339 }
1340
1341 int HttpCache::Transaction::DoCacheQueryData() {
1342 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE;
1343 return entry_->disk_entry->ReadyForSparseIO(io_callback_);
1344 }
1345
1346 int HttpCache::Transaction::DoCacheQueryDataComplete(int result) {
1347 DCHECK_EQ(OK, result);
1348 if (!cache_.get())
1349 return ERR_UNEXPECTED;
1350
1351 return ValidateEntryHeadersAndContinue();
1352 }
1353
1430 // We may end up here multiple times for a given request. 1354 // We may end up here multiple times for a given request.
1431 int HttpCache::Transaction::DoStartPartialCacheValidation() { 1355 int HttpCache::Transaction::DoStartPartialCacheValidation() {
1432 if (mode_ == NONE) 1356 if (mode_ == NONE)
1433 return OK; 1357 return OK;
1434 1358
1435 next_state_ = STATE_COMPLETE_PARTIAL_CACHE_VALIDATION; 1359 next_state_ = STATE_COMPLETE_PARTIAL_CACHE_VALIDATION;
1436 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); 1360 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_);
1437 } 1361 }
1438 1362
1439 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { 1363 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) {
(...skipping 15 matching lines...) Expand all
1455 &custom_request_->extra_headers); 1379 &custom_request_->extra_headers);
1456 1380
1457 if (reading_ && partial_->IsCurrentRangeCached()) { 1381 if (reading_ && partial_->IsCurrentRangeCached()) {
1458 next_state_ = STATE_CACHE_READ_DATA; 1382 next_state_ = STATE_CACHE_READ_DATA;
1459 return OK; 1383 return OK;
1460 } 1384 }
1461 1385
1462 return BeginCacheValidation(); 1386 return BeginCacheValidation();
1463 } 1387 }
1464 1388
1389 int HttpCache::Transaction::DoSendRequest() {
1390 DCHECK(mode_ & WRITE || mode_ == NONE);
1391 DCHECK(!network_trans_.get());
1392
1393 send_request_since_ = TimeTicks::Now();
1394
1395 // Create a network transaction.
1396 int rv =
1397 cache_->network_layer_->CreateTransaction(priority_, &network_trans_);
1398 if (rv != OK)
1399 return rv;
1400 network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_);
1401 network_trans_->SetBeforeProxyHeadersSentCallback(
1402 before_proxy_headers_sent_callback_);
1403
1404 // Old load timing information, if any, is now obsolete.
1405 old_network_trans_load_timing_.reset();
1406
1407 if (websocket_handshake_stream_base_create_helper_)
1408 network_trans_->SetWebSocketHandshakeStreamCreateHelper(
1409 websocket_handshake_stream_base_create_helper_);
1410
1411 next_state_ = STATE_SEND_REQUEST_COMPLETE;
1412 rv = network_trans_->Start(request_, io_callback_, net_log_);
1413 return rv;
1414 }
1415
1416 int HttpCache::Transaction::DoSendRequestComplete(int result) {
1417 if (!cache_.get())
1418 return ERR_UNEXPECTED;
1419
1420 // If we tried to conditionalize the request and failed, we know
1421 // we won't be reading from the cache after this point.
1422 if (couldnt_conditionalize_request_)
1423 mode_ = WRITE;
1424
1425 if (result == OK) {
1426 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST;
1427 return OK;
1428 }
1429
1430 const HttpResponseInfo* response = network_trans_->GetResponseInfo();
1431 response_.network_accessed = response->network_accessed;
1432
1433 // Do not record requests that have network errors or restarts.
1434 UpdateTransactionPattern(PATTERN_NOT_COVERED);
1435 if (IsCertificateError(result)) {
1436 // If we get a certificate error, then there is a certificate in ssl_info,
1437 // so GetResponseInfo() should never return NULL here.
1438 DCHECK(response);
1439 response_.ssl_info = response->ssl_info;
1440 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
1441 DCHECK(response);
1442 response_.cert_request_info = response->cert_request_info;
1443 } else if (response_.was_cached) {
1444 DoneWritingToEntry(true);
1445 }
1446
1447 return result;
1448 }
1449
1450 // We received the response headers and there is no error.
1451 int HttpCache::Transaction::DoSuccessfulSendRequest() {
1452 DCHECK(!new_response_);
1453 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo();
1454
1455 if (new_response->headers->response_code() == 401 ||
1456 new_response->headers->response_code() == 407) {
1457 auth_response_ = *new_response;
1458 if (!reading_)
1459 return OK;
1460
1461 // We initiated a second request the caller doesn't know about. We should be
1462 // able to authenticate this request because we should have authenticated
1463 // this URL moments ago.
1464 if (IsReadyToRestartForAuth()) {
1465 DCHECK(!response_.auth_challenge.get());
1466 next_state_ = STATE_SEND_REQUEST_COMPLETE;
1467 // In theory we should check to see if there are new cookies, but there
1468 // is no way to do that from here.
1469 return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_);
1470 }
1471
1472 // We have to perform cleanup at this point so that at least the next
1473 // request can succeed. We do not retry at this point, because data
1474 // has been read and we have no way to gather credentials. We would
1475 // fail again, and potentially loop. This can happen if the credentials
1476 // expire while chrome is suspended.
1477 if (entry_)
1478 DoomPartialEntry(false);
1479 mode_ = NONE;
1480 partial_.reset();
1481 ResetNetworkTransaction();
1482 return ERR_CACHE_AUTH_FAILURE_AFTER_READ;
1483 }
1484
1485 new_response_ = new_response;
1486 if (!ValidatePartialResponse() && !auth_response_.headers.get()) {
1487 // Something went wrong with this request and we have to restart it.
1488 // If we have an authentication response, we are exposed to weird things
1489 // hapenning if the user cancels the authentication before we receive
1490 // the new response.
1491 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST);
1492 UpdateTransactionPattern(PATTERN_NOT_COVERED);
1493 response_ = HttpResponseInfo();
1494 ResetNetworkTransaction();
1495 new_response_ = NULL;
1496 next_state_ = STATE_SEND_REQUEST;
1497 return OK;
1498 }
1499
1500 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) {
1501 // We have stored the full entry, but it changed and the server is
1502 // sending a range. We have to delete the old entry.
1503 UpdateTransactionPattern(PATTERN_NOT_COVERED);
1504 DoneWritingToEntry(false);
1505 }
1506
1507 if (mode_ == WRITE &&
1508 transaction_pattern_ != PATTERN_ENTRY_CANT_CONDITIONALIZE) {
1509 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED);
1510 }
1511
1512 // Invalidate any cached GET with a successful PUT or DELETE.
1513 if (mode_ == WRITE &&
1514 (request_->method == "PUT" || request_->method == "DELETE")) {
1515 if (NonErrorResponse(new_response->headers->response_code())) {
1516 int ret = cache_->DoomEntry(cache_key_, NULL);
1517 DCHECK_EQ(OK, ret);
1518 }
1519 cache_->DoneWritingToEntry(entry_, true);
1520 entry_ = NULL;
1521 mode_ = NONE;
1522 }
1523
1524 // Invalidate any cached GET with a successful POST.
1525 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) &&
1526 request_->method == "POST" &&
1527 NonErrorResponse(new_response->headers->response_code())) {
1528 cache_->DoomMainEntryForUrl(request_->url);
1529 }
1530
1531 RecordNoStoreHeaderHistogram(request_->load_flags, new_response);
1532
1533 if (new_response_->headers->response_code() == 416 &&
1534 (request_->method == "GET" || request_->method == "POST")) {
1535 // If there is an active entry it may be destroyed with this transaction.
1536 response_ = *new_response_;
1537 return OK;
1538 }
1539
1540 // Are we expecting a response to a conditional query?
1541 if (mode_ == READ_WRITE || mode_ == UPDATE) {
1542 if (new_response->headers->response_code() == 304 || handling_206_) {
1543 UpdateTransactionPattern(PATTERN_ENTRY_VALIDATED);
1544 next_state_ = STATE_UPDATE_CACHED_RESPONSE;
1545 return OK;
1546 }
1547 UpdateTransactionPattern(PATTERN_ENTRY_UPDATED);
1548 mode_ = WRITE;
1549 }
1550
1551 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE;
1552 return OK;
1553 }
1554
1465 // We received 304 or 206 and we want to update the cached response headers. 1555 // We received 304 or 206 and we want to update the cached response headers.
1466 int HttpCache::Transaction::DoUpdateCachedResponse() { 1556 int HttpCache::Transaction::DoUpdateCachedResponse() {
1467 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE; 1557 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE;
1468 int rv = OK; 1558 int rv = OK;
1469 // Update the cached response based on the headers and properties of 1559 // Update the cached response based on the headers and properties of
1470 // new_response_. 1560 // new_response_.
1471 response_.headers->Update(*new_response_->headers.get()); 1561 response_.headers->Update(*new_response_->headers.get());
1472 response_.response_time = new_response_->response_time; 1562 response_.response_time = new_response_->response_time;
1473 response_.request_time = new_response_->request_time; 1563 response_.request_time = new_response_->request_time;
1474 response_.network_accessed = new_response_->network_accessed; 1564 response_.network_accessed = new_response_->network_accessed;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; 1653 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
1564 return OK; 1654 return OK;
1565 } 1655 }
1566 1656
1567 target_state_ = STATE_TRUNCATE_CACHED_DATA; 1657 target_state_ = STATE_TRUNCATE_CACHED_DATA;
1568 next_state_ = truncated_ ? STATE_CACHE_WRITE_TRUNCATED_RESPONSE : 1658 next_state_ = truncated_ ? STATE_CACHE_WRITE_TRUNCATED_RESPONSE :
1569 STATE_CACHE_WRITE_RESPONSE; 1659 STATE_CACHE_WRITE_RESPONSE;
1570 return OK; 1660 return OK;
1571 } 1661 }
1572 1662
1663 int HttpCache::Transaction::DoCacheWriteResponse() {
1664 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
1665 tracked_objects::ScopedTracker tracking_profile(
1666 FROM_HERE_WITH_EXPLICIT_FUNCTION(
1667 "422516 HttpCache::Transaction::DoCacheWriteResponse"));
1668
1669 if (entry_) {
1670 if (net_log_.IsCapturing())
1671 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
1672 }
1673 return WriteResponseInfoToEntry(false);
1674 }
1675
1676 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() {
1677 if (entry_) {
1678 if (net_log_.IsCapturing())
1679 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
1680 }
1681 return WriteResponseInfoToEntry(true);
1682 }
1683
1684 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) {
1685 next_state_ = target_state_;
1686 target_state_ = STATE_NONE;
1687 if (!entry_)
1688 return OK;
1689 if (net_log_.IsCapturing()) {
1690 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO,
1691 result);
1692 }
1693
1694 // Balance the AddRef from WriteResponseInfoToEntry.
1695 if (result != io_buf_len_) {
1696 DLOG(ERROR) << "failed to write response info to cache";
1697 DoneWritingToEntry(false);
1698 }
1699 return OK;
1700 }
1573 int HttpCache::Transaction::DoTruncateCachedData() { 1701 int HttpCache::Transaction::DoTruncateCachedData() {
1574 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; 1702 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE;
1575 if (!entry_) 1703 if (!entry_)
1576 return OK; 1704 return OK;
1577 if (net_log_.IsCapturing()) 1705 if (net_log_.IsCapturing())
1578 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_DATA); 1706 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_DATA);
1579 // Truncate the stream. 1707 // Truncate the stream.
1580 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); 1708 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_);
1581 } 1709 }
1582 1710
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 next_state_ = STATE_CACHE_READ_DATA; 1758 next_state_ = STATE_CACHE_READ_DATA;
1631 } 1759 }
1632 } else if (mode_ != NONE) { 1760 } else if (mode_ != NONE) {
1633 // We are about to return the headers for a byte-range request to the user, 1761 // We are about to return the headers for a byte-range request to the user,
1634 // so let's fix them. 1762 // so let's fix them.
1635 partial_->FixResponseHeaders(response_.headers.get(), true); 1763 partial_->FixResponseHeaders(response_.headers.get(), true);
1636 } 1764 }
1637 return OK; 1765 return OK;
1638 } 1766 }
1639 1767
1640 int HttpCache::Transaction::DoCacheReadResponse() {
1641 DCHECK(entry_);
1642 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE;
1643
1644 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex);
1645 read_buf_ = new IOBuffer(io_buf_len_);
1646
1647 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO);
1648 return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(),
1649 io_buf_len_, io_callback_);
1650 }
1651
1652 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
1653 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result);
1654 if (result != io_buf_len_ ||
1655 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_,
1656 &response_, &truncated_)) {
1657 return OnCacheReadError(result, true);
1658 }
1659
1660 // cert_cache() will be null if the CertCacheTrial field trial is disabled.
1661 if (cache_->cert_cache() && response_.ssl_info.is_valid())
1662 ReadCertChain();
1663
1664 // Some resources may have slipped in as truncated when they're not.
1665 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1666 if (response_.headers->GetContentLength() == current_size)
1667 truncated_ = false;
1668
1669 if ((response_.unused_since_prefetch &&
1670 !(request_->load_flags & LOAD_PREFETCH)) ||
1671 (!response_.unused_since_prefetch &&
1672 (request_->load_flags & LOAD_PREFETCH))) {
1673 // Either this is the first use of an entry since it was prefetched or
1674 // this is a prefetch. The value of response.unused_since_prefetch is valid
1675 // for this transaction but the bit needs to be flipped in storage.
1676 next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH;
1677 return OK;
1678 }
1679
1680 next_state_ = STATE_CACHE_DISPATCH_VALIDATION;
1681 return OK;
1682 }
1683
1684 int HttpCache::Transaction::DoCacheDispatchValidation() {
1685 // We now have access to the cache entry.
1686 //
1687 // o if we are a reader for the transaction, then we can start reading the
1688 // cache entry.
1689 //
1690 // o if we can read or write, then we should check if the cache entry needs
1691 // to be validated and then issue a network request if needed or just read
1692 // from the cache if the cache entry is already valid.
1693 //
1694 // o if we are set to UPDATE, then we are handling an externally
1695 // conditionalized request (if-modified-since / if-none-match). We check
1696 // if the request headers define a validation request.
1697 //
1698 int result = ERR_FAILED;
1699 switch (mode_) {
1700 case READ:
1701 UpdateTransactionPattern(PATTERN_ENTRY_USED);
1702 result = BeginCacheRead();
1703 break;
1704 case READ_WRITE:
1705 result = BeginPartialCacheValidation();
1706 break;
1707 case UPDATE:
1708 result = BeginExternallyConditionalizedRequest();
1709 break;
1710 case WRITE:
1711 default:
1712 NOTREACHED();
1713 }
1714 return result;
1715 }
1716
1717 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch() {
1718 // Write back the toggled value for the next use of this entry.
1719 response_.unused_since_prefetch = !response_.unused_since_prefetch;
1720
1721 // TODO(jkarlin): If DoUpdateCachedResponse is also called for this
1722 // transaction then metadata will be written to cache twice. If prefetching
1723 // becomes more common, consider combining the writes.
1724 target_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE;
1725 next_state_ = STATE_CACHE_WRITE_RESPONSE;
1726 return OK;
1727 }
1728
1729 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetchComplete(
1730 int result) {
1731 // Restore the original value for this transaction.
1732 response_.unused_since_prefetch = !response_.unused_since_prefetch;
1733 next_state_ = STATE_CACHE_DISPATCH_VALIDATION;
1734 return OK;
1735 }
1736
1737 int HttpCache::Transaction::DoCacheWriteResponse() {
1738 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
1739 tracked_objects::ScopedTracker tracking_profile(
1740 FROM_HERE_WITH_EXPLICIT_FUNCTION(
1741 "422516 HttpCache::Transaction::DoCacheWriteResponse"));
1742
1743 if (entry_) {
1744 if (net_log_.IsCapturing())
1745 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
1746 }
1747 return WriteResponseInfoToEntry(false);
1748 }
1749
1750 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() {
1751 if (entry_) {
1752 if (net_log_.IsCapturing())
1753 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
1754 }
1755 return WriteResponseInfoToEntry(true);
1756 }
1757
1758 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) {
1759 next_state_ = target_state_;
1760 target_state_ = STATE_NONE;
1761 if (!entry_)
1762 return OK;
1763 if (net_log_.IsCapturing()) {
1764 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO,
1765 result);
1766 }
1767
1768 // Balance the AddRef from WriteResponseInfoToEntry.
1769 if (result != io_buf_len_) {
1770 DLOG(ERROR) << "failed to write response info to cache";
1771 DoneWritingToEntry(false);
1772 }
1773 return OK;
1774 }
1775
1776 int HttpCache::Transaction::DoCacheReadMetadata() { 1768 int HttpCache::Transaction::DoCacheReadMetadata() {
1777 DCHECK(entry_); 1769 DCHECK(entry_);
1778 DCHECK(!response_.metadata.get()); 1770 DCHECK(!response_.metadata.get());
1779 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; 1771 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE;
1780 1772
1781 response_.metadata = 1773 response_.metadata =
1782 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); 1774 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex));
1783 1775
1784 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); 1776 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO);
1785 return entry_->disk_entry->ReadData(kMetadataIndex, 0, 1777 return entry_->disk_entry->ReadData(kMetadataIndex, 0,
1786 response_.metadata.get(), 1778 response_.metadata.get(),
1787 response_.metadata->size(), 1779 response_.metadata->size(),
1788 io_callback_); 1780 io_callback_);
1789 } 1781 }
1790 1782
1791 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { 1783 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) {
1792 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); 1784 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result);
1793 if (result != response_.metadata->size()) 1785 if (result != response_.metadata->size())
1794 return OnCacheReadError(result, false); 1786 return OnCacheReadError(result, false);
1795 return OK; 1787 return OK;
1796 } 1788 }
1797 1789
1798 int HttpCache::Transaction::DoCacheQueryData() { 1790 int HttpCache::Transaction::DoNetworkRead() {
1799 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; 1791 next_state_ = STATE_NETWORK_READ_COMPLETE;
1800 return entry_->disk_entry->ReadyForSparseIO(io_callback_); 1792 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_);
1801 } 1793 }
1802 1794
1803 int HttpCache::Transaction::DoCacheQueryDataComplete(int result) { 1795 int HttpCache::Transaction::DoNetworkReadComplete(int result) {
1804 DCHECK_EQ(OK, result); 1796 DCHECK(mode_ & WRITE || mode_ == NONE);
1797
1805 if (!cache_.get()) 1798 if (!cache_.get())
1806 return ERR_UNEXPECTED; 1799 return ERR_UNEXPECTED;
1807 1800
1808 return ValidateEntryHeadersAndContinue(); 1801 // If there is an error or we aren't saving the data, we are done; just wait
1802 // until the destructor runs to see if we can keep the data.
1803 if (mode_ == NONE || result < 0)
1804 return result;
1805
1806 next_state_ = STATE_CACHE_WRITE_DATA;
1807 return result;
1809 } 1808 }
1810 1809
1811 int HttpCache::Transaction::DoCacheReadData() { 1810 int HttpCache::Transaction::DoCacheReadData() {
1812 DCHECK(entry_); 1811 DCHECK(entry_);
1813 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; 1812 next_state_ = STATE_CACHE_READ_DATA_COMPLETE;
1814 1813
1815 if (net_log_.IsCapturing()) 1814 if (net_log_.IsCapturing())
1816 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA); 1815 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA);
1817 if (partial_.get()) { 1816 if (partial_.get()) {
1818 return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_, 1817 return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_,
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 mode_ = READ; 2604 mode_ = READ;
2606 2605
2607 if (request_->method == "HEAD") 2606 if (request_->method == "HEAD")
2608 FixHeadersForHead(); 2607 FixHeadersForHead();
2609 2608
2610 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) 2609 if (entry_->disk_entry->GetDataSize(kMetadataIndex))
2611 next_state_ = STATE_CACHE_READ_METADATA; 2610 next_state_ = STATE_CACHE_READ_METADATA;
2612 return OK; 2611 return OK;
2613 } 2612 }
2614 2613
2615
2616 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { 2614 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) {
2617 read_buf_ = data; 2615 read_buf_ = data;
2618 io_buf_len_ = data_len; 2616 io_buf_len_ = data_len;
2619 next_state_ = STATE_NETWORK_READ; 2617 next_state_ = STATE_NETWORK_READ;
2620 return DoLoop(OK); 2618 return DoLoop(OK);
2621 } 2619 }
2622 2620
2623 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) { 2621 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) {
2624 if (request_->method == "HEAD") 2622 if (request_->method == "HEAD")
2625 return 0; 2623 return 0;
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
2931 default: 2929 default:
2932 NOTREACHED(); 2930 NOTREACHED();
2933 } 2931 }
2934 } 2932 }
2935 2933
2936 void HttpCache::Transaction::OnIOComplete(int result) { 2934 void HttpCache::Transaction::OnIOComplete(int result) {
2937 DoLoop(result); 2935 DoLoop(result);
2938 } 2936 }
2939 2937
2940 } // namespace net 2938 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698