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