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