Chromium Code Reviews| 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 23 matching lines...) Expand all Loading... | |
| 1606 if (entry_) { | 1734 if (entry_) { |
| 1607 if (net_log_.IsCapturing()) { | 1735 if (net_log_.IsCapturing()) { |
| 1608 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO, | 1736 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO, |
| 1609 result); | 1737 result); |
| 1610 } | 1738 } |
| 1611 } | 1739 } |
| 1612 | 1740 |
| 1613 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1741 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1614 return OK; | 1742 return OK; |
| 1615 } | 1743 } |
| 1616 | |
|
rvargas (doing something else)
2015/07/13 19:18:56
need this line
hubbe
2015/07/13 19:29:15
Done.
| |
| 1617 int HttpCache::Transaction::DoPartialHeadersReceived() { | 1744 int HttpCache::Transaction::DoPartialHeadersReceived() { |
| 1618 new_response_ = NULL; | 1745 new_response_ = NULL; |
| 1619 if (entry_ && !partial_.get() && | 1746 if (entry_ && !partial_.get() && |
| 1620 entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1747 entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 1621 next_state_ = STATE_CACHE_READ_METADATA; | 1748 next_state_ = STATE_CACHE_READ_METADATA; |
| 1622 | 1749 |
| 1623 if (!partial_.get()) | 1750 if (!partial_.get()) |
| 1624 return OK; | 1751 return OK; |
| 1625 | 1752 |
| 1626 if (reading_) { | 1753 if (reading_) { |
| 1627 if (network_trans_.get()) { | 1754 if (network_trans_.get()) { |
| 1628 next_state_ = STATE_NETWORK_READ; | 1755 next_state_ = STATE_NETWORK_READ; |
| 1629 } else { | 1756 } else { |
| 1630 next_state_ = STATE_CACHE_READ_DATA; | 1757 next_state_ = STATE_CACHE_READ_DATA; |
| 1631 } | 1758 } |
| 1632 } else if (mode_ != NONE) { | 1759 } else if (mode_ != NONE) { |
| 1633 // We are about to return the headers for a byte-range request to the user, | 1760 // We are about to return the headers for a byte-range request to the user, |
| 1634 // so let's fix them. | 1761 // so let's fix them. |
| 1635 partial_->FixResponseHeaders(response_.headers.get(), true); | 1762 partial_->FixResponseHeaders(response_.headers.get(), true); |
| 1636 } | 1763 } |
| 1637 return OK; | 1764 return OK; |
| 1638 } | 1765 } |
| 1639 | 1766 |
| 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() { | 1767 int HttpCache::Transaction::DoCacheReadMetadata() { |
| 1777 DCHECK(entry_); | 1768 DCHECK(entry_); |
| 1778 DCHECK(!response_.metadata.get()); | 1769 DCHECK(!response_.metadata.get()); |
| 1779 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; | 1770 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; |
| 1780 | 1771 |
| 1781 response_.metadata = | 1772 response_.metadata = |
| 1782 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); | 1773 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); |
| 1783 | 1774 |
| 1784 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); | 1775 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
| 1785 return entry_->disk_entry->ReadData(kMetadataIndex, 0, | 1776 return entry_->disk_entry->ReadData(kMetadataIndex, 0, |
| 1786 response_.metadata.get(), | 1777 response_.metadata.get(), |
| 1787 response_.metadata->size(), | 1778 response_.metadata->size(), |
| 1788 io_callback_); | 1779 io_callback_); |
| 1789 } | 1780 } |
| 1790 | 1781 |
| 1791 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { | 1782 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { |
| 1792 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1783 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
| 1793 if (result != response_.metadata->size()) | 1784 if (result != response_.metadata->size()) |
| 1794 return OnCacheReadError(result, false); | 1785 return OnCacheReadError(result, false); |
| 1795 return OK; | 1786 return OK; |
| 1796 } | 1787 } |
| 1797 | 1788 |
| 1798 int HttpCache::Transaction::DoCacheQueryData() { | 1789 int HttpCache::Transaction::DoNetworkRead() { |
| 1799 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; | 1790 next_state_ = STATE_NETWORK_READ_COMPLETE; |
| 1800 return entry_->disk_entry->ReadyForSparseIO(io_callback_); | 1791 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); |
| 1801 } | 1792 } |
| 1802 | 1793 |
| 1803 int HttpCache::Transaction::DoCacheQueryDataComplete(int result) { | 1794 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| 1804 DCHECK_EQ(OK, result); | 1795 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 1796 | |
| 1805 if (!cache_.get()) | 1797 if (!cache_.get()) |
| 1806 return ERR_UNEXPECTED; | 1798 return ERR_UNEXPECTED; |
| 1807 | 1799 |
| 1808 return ValidateEntryHeadersAndContinue(); | 1800 // If there is an error or we aren't saving the data, we are done; just wait |
| 1801 // until the destructor runs to see if we can keep the data. | |
| 1802 if (mode_ == NONE || result < 0) | |
| 1803 return result; | |
| 1804 | |
| 1805 next_state_ = STATE_CACHE_WRITE_DATA; | |
| 1806 return result; | |
| 1809 } | 1807 } |
| 1810 | 1808 |
| 1811 int HttpCache::Transaction::DoCacheReadData() { | 1809 int HttpCache::Transaction::DoCacheReadData() { |
| 1812 DCHECK(entry_); | 1810 DCHECK(entry_); |
| 1813 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; | 1811 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; |
| 1814 | 1812 |
| 1815 if (net_log_.IsCapturing()) | 1813 if (net_log_.IsCapturing()) |
| 1816 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA); | 1814 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA); |
| 1817 if (partial_.get()) { | 1815 if (partial_.get()) { |
| 1818 return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_, | 1816 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; | 2603 mode_ = READ; |
| 2606 | 2604 |
| 2607 if (request_->method == "HEAD") | 2605 if (request_->method == "HEAD") |
| 2608 FixHeadersForHead(); | 2606 FixHeadersForHead(); |
| 2609 | 2607 |
| 2610 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 2608 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 2611 next_state_ = STATE_CACHE_READ_METADATA; | 2609 next_state_ = STATE_CACHE_READ_METADATA; |
| 2612 return OK; | 2610 return OK; |
| 2613 } | 2611 } |
| 2614 | 2612 |
| 2615 | |
| 2616 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { | 2613 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { |
| 2617 read_buf_ = data; | 2614 read_buf_ = data; |
| 2618 io_buf_len_ = data_len; | 2615 io_buf_len_ = data_len; |
| 2619 next_state_ = STATE_NETWORK_READ; | 2616 next_state_ = STATE_NETWORK_READ; |
| 2620 return DoLoop(OK); | 2617 return DoLoop(OK); |
| 2621 } | 2618 } |
| 2622 | 2619 |
| 2623 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) { | 2620 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) { |
| 2624 if (request_->method == "HEAD") | 2621 if (request_->method == "HEAD") |
| 2625 return 0; | 2622 return 0; |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2931 default: | 2928 default: |
| 2932 NOTREACHED(); | 2929 NOTREACHED(); |
| 2933 } | 2930 } |
| 2934 } | 2931 } |
| 2935 | 2932 |
| 2936 void HttpCache::Transaction::OnIOComplete(int result) { | 2933 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2937 DoLoop(result); | 2934 DoLoop(result); |
| 2938 } | 2935 } |
| 2939 | 2936 |
| 2940 } // namespace net | 2937 } // namespace net |
| OLD | NEW |