| 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/trace_event/trace_event.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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 weak_factory_(this) { | 173 weak_factory_(this) { |
| 173 static_assert(HttpCache::Transaction::kNumValidationHeaders == | 174 static_assert(HttpCache::Transaction::kNumValidationHeaders == |
| 174 arraysize(kValidationHeaders), | 175 arraysize(kValidationHeaders), |
| 175 "invalid number of validation headers"); | 176 "invalid number of validation headers"); |
| 176 | 177 |
| 177 io_callback_ = base::Bind(&Transaction::OnIOComplete, | 178 io_callback_ = base::Bind(&Transaction::OnIOComplete, |
| 178 weak_factory_.GetWeakPtr()); | 179 weak_factory_.GetWeakPtr()); |
| 179 } | 180 } |
| 180 | 181 |
| 181 HttpCache::Transaction::~Transaction() { | 182 HttpCache::Transaction::~Transaction() { |
| 183 TRACE_EVENT0("toplevel", "HttpCache::Transaction::~Transaction"); |
| 184 |
| 182 // We may have to issue another IO, but we should never invoke the callback_ | 185 // We may have to issue another IO, but we should never invoke the callback_ |
| 183 // after this point. | 186 // after this point. |
| 184 callback_.Reset(); | 187 callback_.Reset(); |
| 185 | 188 |
| 186 if (cache_) { | 189 if (cache_) { |
| 187 if (entry_) { | 190 if (entry_) { |
| 188 bool cancel_request = reading_ && response_.headers.get(); | 191 bool cancel_request = reading_ && response_.headers.get(); |
| 189 if (cancel_request) { | 192 if (cancel_request) { |
| 190 if (partial_) { | 193 if (partial_) { |
| 191 entry_->disk_entry->CancelSparseIO(); | 194 entry_->disk_entry->CancelSparseIO(); |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 | 863 |
| 861 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 864 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 862 read_buf_ = NULL; // Release the buffer before invoking the callback. | 865 read_buf_ = NULL; // Release the buffer before invoking the callback. |
| 863 base::ResetAndReturn(&callback_).Run(rv); | 866 base::ResetAndReturn(&callback_).Run(rv); |
| 864 } | 867 } |
| 865 | 868 |
| 866 return rv; | 869 return rv; |
| 867 } | 870 } |
| 868 | 871 |
| 869 int HttpCache::Transaction::DoGetBackend() { | 872 int HttpCache::Transaction::DoGetBackend() { |
| 873 TRACE_EVENT0("toplevel", "HttpCache::Transaction::DoGetBackend"); |
| 870 cache_pending_ = true; | 874 cache_pending_ = true; |
| 871 next_state_ = STATE_GET_BACKEND_COMPLETE; | 875 next_state_ = STATE_GET_BACKEND_COMPLETE; |
| 872 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_GET_BACKEND); | 876 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_GET_BACKEND); |
| 873 return cache_->GetBackendForTransaction(this); | 877 return cache_->GetBackendForTransaction(this); |
| 874 } | 878 } |
| 875 | 879 |
| 876 int HttpCache::Transaction::DoGetBackendComplete(int result) { | 880 int HttpCache::Transaction::DoGetBackendComplete(int result) { |
| 881 TRACE_EVENT0("toplevel", "HttpCache::Transaction::DoGetBackendComplete"); |
| 877 DCHECK(result == OK || result == ERR_FAILED); | 882 DCHECK(result == OK || result == ERR_FAILED); |
| 878 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_GET_BACKEND, | 883 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_GET_BACKEND, |
| 879 result); | 884 result); |
| 880 cache_pending_ = false; | 885 cache_pending_ = false; |
| 881 | 886 |
| 882 if (!ShouldPassThrough()) { | 887 if (!ShouldPassThrough()) { |
| 883 cache_key_ = cache_->GenerateCacheKey(request_); | 888 cache_key_ = cache_->GenerateCacheKey(request_); |
| 884 | 889 |
| 885 // Requested cache access mode. | 890 // Requested cache access mode. |
| 886 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { | 891 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 next_state_ = STATE_INIT_ENTRY; | 937 next_state_ = STATE_INIT_ENTRY; |
| 933 } | 938 } |
| 934 | 939 |
| 935 // This is only set if we have something to do with the response. | 940 // This is only set if we have something to do with the response. |
| 936 range_requested_ = (partial_.get() != NULL); | 941 range_requested_ = (partial_.get() != NULL); |
| 937 | 942 |
| 938 return OK; | 943 return OK; |
| 939 } | 944 } |
| 940 | 945 |
| 941 int HttpCache::Transaction::DoInitEntry() { | 946 int HttpCache::Transaction::DoInitEntry() { |
| 947 TRACE_EVENT0("toplevel", "HttpCache::Transaction::DoInitEntry"); |
| 942 DCHECK(!new_entry_); | 948 DCHECK(!new_entry_); |
| 943 | 949 |
| 944 if (!cache_.get()) | 950 if (!cache_.get()) |
| 945 return ERR_UNEXPECTED; | 951 return ERR_UNEXPECTED; |
| 946 | 952 |
| 947 if (mode_ == WRITE) { | 953 if (mode_ == WRITE) { |
| 948 next_state_ = STATE_DOOM_ENTRY; | 954 next_state_ = STATE_DOOM_ENTRY; |
| 949 return OK; | 955 return OK; |
| 950 } | 956 } |
| 951 | 957 |
| 952 next_state_ = STATE_OPEN_ENTRY; | 958 next_state_ = STATE_OPEN_ENTRY; |
| 953 return OK; | 959 return OK; |
| 954 } | 960 } |
| 955 | 961 |
| 956 int HttpCache::Transaction::DoOpenEntry() { | 962 int HttpCache::Transaction::DoOpenEntry() { |
| 963 TRACE_EVENT0("toplevel", "HttpCache::Transaction::DoOpenEntry"); |
| 957 DCHECK(!new_entry_); | 964 DCHECK(!new_entry_); |
| 958 next_state_ = STATE_OPEN_ENTRY_COMPLETE; | 965 next_state_ = STATE_OPEN_ENTRY_COMPLETE; |
| 959 cache_pending_ = true; | 966 cache_pending_ = true; |
| 960 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); | 967 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); |
| 961 first_cache_access_since_ = TimeTicks::Now(); | 968 first_cache_access_since_ = TimeTicks::Now(); |
| 962 return cache_->OpenEntry(cache_key_, &new_entry_, this); | 969 return cache_->OpenEntry(cache_key_, &new_entry_, this); |
| 963 } | 970 } |
| 964 | 971 |
| 965 int HttpCache::Transaction::DoOpenEntryComplete(int result) { | 972 int HttpCache::Transaction::DoOpenEntryComplete(int result) { |
| 973 TRACE_EVENT0("toplevel", "HttpCache::Transaction::DoOpenEntryComplete"); |
| 966 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is | 974 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is |
| 967 // OK, otherwise the cache will end up with an active entry without any | 975 // OK, otherwise the cache will end up with an active entry without any |
| 968 // transaction attached. | 976 // transaction attached. |
| 969 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); | 977 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); |
| 970 cache_pending_ = false; | 978 cache_pending_ = false; |
| 971 if (result == OK) { | 979 if (result == OK) { |
| 972 next_state_ = STATE_ADD_TO_ENTRY; | 980 next_state_ = STATE_ADD_TO_ENTRY; |
| 973 return OK; | 981 return OK; |
| 974 } | 982 } |
| 975 | 983 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 DLOG(WARNING) << "Unable to create cache entry"; | 1061 DLOG(WARNING) << "Unable to create cache entry"; |
| 1054 mode_ = NONE; | 1062 mode_ = NONE; |
| 1055 if (partial_) | 1063 if (partial_) |
| 1056 partial_->RestoreHeaders(&custom_request_->extra_headers); | 1064 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 1057 next_state_ = STATE_SEND_REQUEST; | 1065 next_state_ = STATE_SEND_REQUEST; |
| 1058 } | 1066 } |
| 1059 return OK; | 1067 return OK; |
| 1060 } | 1068 } |
| 1061 | 1069 |
| 1062 int HttpCache::Transaction::DoAddToEntry() { | 1070 int HttpCache::Transaction::DoAddToEntry() { |
| 1071 TRACE_EVENT0("toplevel", "HttpCache::Transaction::DoAddToEntry"); |
| 1063 DCHECK(new_entry_); | 1072 DCHECK(new_entry_); |
| 1064 cache_pending_ = true; | 1073 cache_pending_ = true; |
| 1065 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; | 1074 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; |
| 1066 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); | 1075 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); |
| 1067 DCHECK(entry_lock_waiting_since_.is_null()); | 1076 DCHECK(entry_lock_waiting_since_.is_null()); |
| 1068 entry_lock_waiting_since_ = TimeTicks::Now(); | 1077 entry_lock_waiting_since_ = TimeTicks::Now(); |
| 1069 int rv = cache_->AddTransactionToEntry(new_entry_, this); | 1078 int rv = cache_->AddTransactionToEntry(new_entry_, this); |
| 1070 if (rv == ERR_IO_PENDING) { | 1079 if (rv == ERR_IO_PENDING) { |
| 1071 if (bypass_lock_for_test_) { | 1080 if (bypass_lock_for_test_) { |
| 1072 OnAddToEntryTimeout(entry_lock_waiting_since_); | 1081 OnAddToEntryTimeout(entry_lock_waiting_since_); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1094 FROM_HERE, | 1103 FROM_HERE, |
| 1095 base::Bind(&HttpCache::Transaction::OnAddToEntryTimeout, | 1104 base::Bind(&HttpCache::Transaction::OnAddToEntryTimeout, |
| 1096 weak_factory_.GetWeakPtr(), entry_lock_waiting_since_), | 1105 weak_factory_.GetWeakPtr(), entry_lock_waiting_since_), |
| 1097 TimeDelta::FromMilliseconds(timeout_milliseconds)); | 1106 TimeDelta::FromMilliseconds(timeout_milliseconds)); |
| 1098 } | 1107 } |
| 1099 } | 1108 } |
| 1100 return rv; | 1109 return rv; |
| 1101 } | 1110 } |
| 1102 | 1111 |
| 1103 int HttpCache::Transaction::DoAddToEntryComplete(int result) { | 1112 int HttpCache::Transaction::DoAddToEntryComplete(int result) { |
| 1113 TRACE_EVENT0("toplevel", "HttpCache::Transaction::DoAddToEntryComplete"); |
| 1104 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY, | 1114 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY, |
| 1105 result); | 1115 result); |
| 1106 const TimeDelta entry_lock_wait = | 1116 const TimeDelta entry_lock_wait = |
| 1107 TimeTicks::Now() - entry_lock_waiting_since_; | 1117 TimeTicks::Now() - entry_lock_waiting_since_; |
| 1108 UMA_HISTOGRAM_TIMES("HttpCache.EntryLockWait", entry_lock_wait); | 1118 UMA_HISTOGRAM_TIMES("HttpCache.EntryLockWait", entry_lock_wait); |
| 1109 | 1119 |
| 1110 entry_lock_waiting_since_ = TimeTicks(); | 1120 entry_lock_waiting_since_ = TimeTicks(); |
| 1111 DCHECK(new_entry_); | 1121 DCHECK(new_entry_); |
| 1112 cache_pending_ = false; | 1122 cache_pending_ = false; |
| 1113 | 1123 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1144 next_state_ = STATE_SEND_REQUEST; | 1154 next_state_ = STATE_SEND_REQUEST; |
| 1145 } else { | 1155 } else { |
| 1146 // We have to read the headers from the cached entry. | 1156 // We have to read the headers from the cached entry. |
| 1147 DCHECK(mode_ & READ_META); | 1157 DCHECK(mode_ & READ_META); |
| 1148 next_state_ = STATE_CACHE_READ_RESPONSE; | 1158 next_state_ = STATE_CACHE_READ_RESPONSE; |
| 1149 } | 1159 } |
| 1150 return OK; | 1160 return OK; |
| 1151 } | 1161 } |
| 1152 | 1162 |
| 1153 int HttpCache::Transaction::DoCacheReadResponse() { | 1163 int HttpCache::Transaction::DoCacheReadResponse() { |
| 1164 TRACE_EVENT0("toplevel", "HttpCache::Transaction::DoCacheReadResponse"); |
| 1154 DCHECK(entry_); | 1165 DCHECK(entry_); |
| 1155 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE; | 1166 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE; |
| 1156 | 1167 |
| 1157 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex); | 1168 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex); |
| 1158 read_buf_ = new IOBuffer(io_buf_len_); | 1169 read_buf_ = new IOBuffer(io_buf_len_); |
| 1159 | 1170 |
| 1160 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); | 1171 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
| 1161 return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(), | 1172 return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(), |
| 1162 io_buf_len_, io_callback_); | 1173 io_buf_len_, io_callback_); |
| 1163 } | 1174 } |
| 1164 | 1175 |
| 1165 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { | 1176 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { |
| 1177 TRACE_EVENT0("toplevel", |
| 1178 "HttpCache::Transaction::DoCacheReadResponseComplete"); |
| 1166 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1179 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
| 1167 if (result != io_buf_len_ || | 1180 if (result != io_buf_len_ || |
| 1168 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, &response_, | 1181 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, &response_, |
| 1169 &truncated_)) { | 1182 &truncated_)) { |
| 1170 return OnCacheReadError(result, true); | 1183 return OnCacheReadError(result, true); |
| 1171 } | 1184 } |
| 1172 | 1185 |
| 1173 // Some resources may have slipped in as truncated when they're not. | 1186 // Some resources may have slipped in as truncated when they're not. |
| 1174 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 1187 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1175 if (response_.headers->GetContentLength() == current_size) | 1188 if (response_.headers->GetContentLength() == current_size) |
| (...skipping 1598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2774 default: | 2787 default: |
| 2775 NOTREACHED(); | 2788 NOTREACHED(); |
| 2776 } | 2789 } |
| 2777 } | 2790 } |
| 2778 | 2791 |
| 2779 void HttpCache::Transaction::OnIOComplete(int result) { | 2792 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2780 DoLoop(result); | 2793 DoLoop(result); |
| 2781 } | 2794 } |
| 2782 | 2795 |
| 2783 } // namespace net | 2796 } // namespace net |
| OLD | NEW |