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" | 7 #include "build/build_config.h" |
8 | 8 |
9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "net/http/http_response_headers.h" | 33 #include "net/http/http_response_headers.h" |
34 #include "net/http/http_transaction_delegate.h" | 34 #include "net/http/http_transaction_delegate.h" |
35 #include "net/http/http_transaction.h" | 35 #include "net/http/http_transaction.h" |
36 #include "net/http/http_util.h" | 36 #include "net/http/http_util.h" |
37 #include "net/http/partial_data.h" | 37 #include "net/http/partial_data.h" |
38 | 38 |
39 using base::Time; | 39 using base::Time; |
40 using base::TimeDelta; | 40 using base::TimeDelta; |
41 using base::TimeTicks; | 41 using base::TimeTicks; |
42 | 42 |
| 43 namespace { |
| 44 |
| 45 // The cutoff for tagging small transactions in histograms; this size was chosen |
| 46 // to cover resources likely to be received in a single TCP window. With an |
| 47 // initial CWND of 10, and an MTU of 1500 bytes, with TCP and HTTP framing |
| 48 // overhead this is a size relatively likely to take only one RTT. |
| 49 const int kSmallResourceMaxBytes = 14 * 1024; |
| 50 |
| 51 } // namespace |
| 52 |
43 namespace net { | 53 namespace net { |
44 | 54 |
45 struct HeaderNameAndValue { | 55 struct HeaderNameAndValue { |
46 const char* name; | 56 const char* name; |
47 const char* value; | 57 const char* value; |
48 }; | 58 }; |
49 | 59 |
50 // If the request includes one of these request headers, then avoid caching | 60 // If the request includes one of these request headers, then avoid caching |
51 // to avoid getting confused. | 61 // to avoid getting confused. |
52 static const HeaderNameAndValue kPassThroughHeaders[] = { | 62 static const HeaderNameAndValue kPassThroughHeaders[] = { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 cache_pending_(false), | 133 cache_pending_(false), |
124 done_reading_(false), | 134 done_reading_(false), |
125 read_offset_(0), | 135 read_offset_(0), |
126 effective_load_flags_(0), | 136 effective_load_flags_(0), |
127 write_len_(0), | 137 write_len_(0), |
128 final_upload_progress_(0), | 138 final_upload_progress_(0), |
129 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 139 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
130 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( | 140 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( |
131 base::Bind(&Transaction::OnIOComplete, | 141 base::Bind(&Transaction::OnIOComplete, |
132 weak_factory_.GetWeakPtr()))), | 142 weak_factory_.GetWeakPtr()))), |
| 143 transaction_pattern_(PATTERN_UNDEFINED), |
| 144 bytes_read_from_cache_(0), |
| 145 bytes_read_from_network_(0), |
133 transaction_delegate_(transaction_delegate) { | 146 transaction_delegate_(transaction_delegate) { |
134 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == | 147 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == |
135 arraysize(kValidationHeaders), | 148 arraysize(kValidationHeaders), |
136 Invalid_number_of_validation_headers); | 149 Invalid_number_of_validation_headers); |
137 } | 150 } |
138 | 151 |
139 HttpCache::Transaction::~Transaction() { | 152 HttpCache::Transaction::~Transaction() { |
140 // We may have to issue another IO, but we should never invoke the callback_ | 153 // We may have to issue another IO, but we should never invoke the callback_ |
141 // after this point. | 154 // after this point. |
142 callback_.Reset(); | 155 callback_.Reset(); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 332 |
320 DCHECK(callback_.is_null()); | 333 DCHECK(callback_.is_null()); |
321 | 334 |
322 if (!cache_) | 335 if (!cache_) |
323 return ERR_UNEXPECTED; | 336 return ERR_UNEXPECTED; |
324 | 337 |
325 // If we have an intermediate auth response at this point, then it means the | 338 // If we have an intermediate auth response at this point, then it means the |
326 // user wishes to read the network response (the error page). If there is a | 339 // user wishes to read the network response (the error page). If there is a |
327 // previous response in the cache then we should leave it intact. | 340 // previous response in the cache then we should leave it intact. |
328 if (auth_response_.headers && mode_ != NONE) { | 341 if (auth_response_.headers && mode_ != NONE) { |
| 342 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
329 DCHECK(mode_ & WRITE); | 343 DCHECK(mode_ & WRITE); |
330 DoneWritingToEntry(mode_ == READ_WRITE); | 344 DoneWritingToEntry(mode_ == READ_WRITE); |
331 mode_ = NONE; | 345 mode_ = NONE; |
332 } | 346 } |
333 | 347 |
334 reading_ = true; | 348 reading_ = true; |
335 int rv; | 349 int rv; |
336 | 350 |
337 switch (mode_) { | 351 switch (mode_) { |
338 case READ_WRITE: | 352 case READ_WRITE: |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 // This is only set if we have something to do with the response. | 731 // This is only set if we have something to do with the response. |
718 range_requested_ = (partial_.get() != NULL); | 732 range_requested_ = (partial_.get() != NULL); |
719 | 733 |
720 return OK; | 734 return OK; |
721 } | 735 } |
722 | 736 |
723 int HttpCache::Transaction::DoSendRequest() { | 737 int HttpCache::Transaction::DoSendRequest() { |
724 DCHECK(mode_ & WRITE || mode_ == NONE); | 738 DCHECK(mode_ & WRITE || mode_ == NONE); |
725 DCHECK(!network_trans_.get()); | 739 DCHECK(!network_trans_.get()); |
726 | 740 |
| 741 send_request_since_ = TimeTicks::Now(); |
| 742 |
727 // Create a network transaction. | 743 // Create a network transaction. |
728 int rv = cache_->network_layer_->CreateTransaction(&network_trans_, NULL); | 744 int rv = cache_->network_layer_->CreateTransaction(&network_trans_, NULL); |
729 if (rv != OK) | 745 if (rv != OK) |
730 return rv; | 746 return rv; |
731 | 747 |
732 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 748 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
733 rv = network_trans_->Start(request_, io_callback_, net_log_); | 749 rv = network_trans_->Start(request_, io_callback_, net_log_); |
734 return rv; | 750 return rv; |
735 } | 751 } |
736 | 752 |
737 int HttpCache::Transaction::DoSendRequestComplete(int result) { | 753 int HttpCache::Transaction::DoSendRequestComplete(int result) { |
738 if (!cache_) | 754 if (!cache_) |
739 return ERR_UNEXPECTED; | 755 return ERR_UNEXPECTED; |
740 | 756 |
741 if (result == OK) { | 757 if (result == OK) { |
742 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 758 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
743 return OK; | 759 return OK; |
744 } | 760 } |
745 | 761 |
| 762 // Do not record requests that have network errors or restarts. |
| 763 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
746 if (IsCertificateError(result)) { | 764 if (IsCertificateError(result)) { |
747 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 765 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
748 // If we get a certificate error, then there is a certificate in ssl_info, | 766 // If we get a certificate error, then there is a certificate in ssl_info, |
749 // so GetResponseInfo() should never return NULL here. | 767 // so GetResponseInfo() should never return NULL here. |
750 DCHECK(response); | 768 DCHECK(response); |
751 response_.ssl_info = response->ssl_info; | 769 response_.ssl_info = response->ssl_info; |
752 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 770 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
753 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 771 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
754 DCHECK(response); | 772 DCHECK(response); |
755 response_.cert_request_info = response->cert_request_info; | 773 response_.cert_request_info = response->cert_request_info; |
(...skipping 10 matching lines...) Expand all Loading... |
766 auth_response_ = *new_response; | 784 auth_response_ = *new_response; |
767 return OK; | 785 return OK; |
768 } | 786 } |
769 | 787 |
770 new_response_ = new_response; | 788 new_response_ = new_response; |
771 if (!ValidatePartialResponse() && !auth_response_.headers) { | 789 if (!ValidatePartialResponse() && !auth_response_.headers) { |
772 // Something went wrong with this request and we have to restart it. | 790 // Something went wrong with this request and we have to restart it. |
773 // If we have an authentication response, we are exposed to weird things | 791 // If we have an authentication response, we are exposed to weird things |
774 // hapenning if the user cancels the authentication before we receive | 792 // hapenning if the user cancels the authentication before we receive |
775 // the new response. | 793 // the new response. |
| 794 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
776 response_ = HttpResponseInfo(); | 795 response_ = HttpResponseInfo(); |
777 network_trans_.reset(); | 796 network_trans_.reset(); |
778 new_response_ = NULL; | 797 new_response_ = NULL; |
779 next_state_ = STATE_SEND_REQUEST; | 798 next_state_ = STATE_SEND_REQUEST; |
780 return OK; | 799 return OK; |
781 } | 800 } |
| 801 bytes_read_from_network_ += new_response_->headers->raw_headers().size(); |
782 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { | 802 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { |
783 // We have stored the full entry, but it changed and the server is | 803 // We have stored the full entry, but it changed and the server is |
784 // sending a range. We have to delete the old entry. | 804 // sending a range. We have to delete the old entry. |
| 805 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
785 DoneWritingToEntry(false); | 806 DoneWritingToEntry(false); |
786 } | 807 } |
787 | |
788 if (new_response_->headers->response_code() == 416) { | 808 if (new_response_->headers->response_code() == 416) { |
789 DCHECK_EQ(NONE, mode_); | 809 DCHECK_EQ(NONE, mode_); |
790 response_ = *new_response_; | 810 response_ = *new_response_; |
791 return OK; | 811 return OK; |
792 } | 812 } |
793 | 813 |
| 814 if (mode_ == WRITE) |
| 815 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED); |
| 816 |
794 if (mode_ == WRITE && | 817 if (mode_ == WRITE && |
795 (request_->method == "PUT" || request_->method == "DELETE")) { | 818 (request_->method == "PUT" || request_->method == "DELETE")) { |
796 if (new_response->headers->response_code() == 200) { | 819 if (new_response->headers->response_code() == 200) { |
797 int ret = cache_->DoomEntry(cache_key_, NULL); | 820 int ret = cache_->DoomEntry(cache_key_, NULL); |
798 DCHECK_EQ(OK, ret); | 821 DCHECK_EQ(OK, ret); |
799 } | 822 } |
800 mode_ = NONE; | 823 mode_ = NONE; |
801 } | 824 } |
802 | 825 |
803 // Are we expecting a response to a conditional query? | 826 // Are we expecting a response to a conditional query? |
804 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 827 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
805 if (new_response->headers->response_code() == 304 || handling_206_) { | 828 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 829 UpdateTransactionPattern(PATTERN_ENTRY_VALIDATED); |
806 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 830 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
807 return OK; | 831 return OK; |
808 } | 832 } |
| 833 UpdateTransactionPattern(PATTERN_ENTRY_UPDATED); |
809 mode_ = WRITE; | 834 mode_ = WRITE; |
810 } | 835 } |
811 | 836 |
812 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; | 837 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; |
813 return OK; | 838 return OK; |
814 } | 839 } |
815 | 840 |
816 int HttpCache::Transaction::DoNetworkRead() { | 841 int HttpCache::Transaction::DoNetworkRead() { |
817 next_state_ = STATE_NETWORK_READ_COMPLETE; | 842 next_state_ = STATE_NETWORK_READ_COMPLETE; |
818 return network_trans_->Read(read_buf_, io_buf_len_, io_callback_); | 843 return network_trans_->Read(read_buf_, io_buf_len_, io_callback_); |
819 } | 844 } |
820 | 845 |
821 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 846 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
822 DCHECK(mode_ & WRITE || mode_ == NONE); | 847 DCHECK(mode_ & WRITE || mode_ == NONE); |
823 | 848 |
824 if (!cache_) | 849 if (!cache_) |
825 return ERR_UNEXPECTED; | 850 return ERR_UNEXPECTED; |
826 | 851 |
| 852 if (result > 0) |
| 853 bytes_read_from_network_ += result; |
| 854 |
827 // If there is an error or we aren't saving the data, we are done; just wait | 855 // If there is an error or we aren't saving the data, we are done; just wait |
828 // until the destructor runs to see if we can keep the data. | 856 // until the destructor runs to see if we can keep the data. |
829 if (mode_ == NONE || result < 0) | 857 if (mode_ == NONE || result < 0) |
830 return result; | 858 return result; |
831 | 859 |
832 next_state_ = STATE_CACHE_WRITE_DATA; | 860 next_state_ = STATE_CACHE_WRITE_DATA; |
833 return result; | 861 return result; |
834 } | 862 } |
835 | 863 |
836 int HttpCache::Transaction::DoInitEntry() { | 864 int HttpCache::Transaction::DoInitEntry() { |
837 DCHECK(!new_entry_); | 865 DCHECK(!new_entry_); |
838 | 866 |
839 if (!cache_) | 867 if (!cache_) |
840 return ERR_UNEXPECTED; | 868 return ERR_UNEXPECTED; |
841 | 869 |
842 if (mode_ == WRITE) { | 870 if (mode_ == WRITE) { |
843 next_state_ = STATE_DOOM_ENTRY; | 871 next_state_ = STATE_DOOM_ENTRY; |
844 return OK; | 872 return OK; |
845 } | 873 } |
846 | 874 |
847 next_state_ = STATE_OPEN_ENTRY; | 875 next_state_ = STATE_OPEN_ENTRY; |
848 return OK; | 876 return OK; |
849 } | 877 } |
850 | 878 |
851 int HttpCache::Transaction::DoOpenEntry() { | 879 int HttpCache::Transaction::DoOpenEntry() { |
852 DCHECK(!new_entry_); | 880 DCHECK(!new_entry_); |
853 next_state_ = STATE_OPEN_ENTRY_COMPLETE; | 881 next_state_ = STATE_OPEN_ENTRY_COMPLETE; |
854 cache_pending_ = true; | 882 cache_pending_ = true; |
855 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); | 883 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); |
| 884 first_cache_access_since_ = TimeTicks::Now(); |
856 ReportCacheActionStart(); | 885 ReportCacheActionStart(); |
857 return cache_->OpenEntry(cache_key_, &new_entry_, this); | 886 return cache_->OpenEntry(cache_key_, &new_entry_, this); |
858 } | 887 } |
859 | 888 |
860 int HttpCache::Transaction::DoOpenEntryComplete(int result) { | 889 int HttpCache::Transaction::DoOpenEntryComplete(int result) { |
861 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is | 890 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is |
862 // OK, otherwise the cache will end up with an active entry without any | 891 // OK, otherwise the cache will end up with an active entry without any |
863 // transaction attached. | 892 // transaction attached. |
864 ReportCacheActionFinish(); | 893 ReportCacheActionFinish(); |
865 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); | 894 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 if (partial_.get()) | 963 if (partial_.get()) |
935 partial_->RestoreHeaders(&custom_request_->extra_headers); | 964 partial_->RestoreHeaders(&custom_request_->extra_headers); |
936 next_state_ = STATE_SEND_REQUEST; | 965 next_state_ = STATE_SEND_REQUEST; |
937 } | 966 } |
938 return OK; | 967 return OK; |
939 } | 968 } |
940 | 969 |
941 int HttpCache::Transaction::DoDoomEntry() { | 970 int HttpCache::Transaction::DoDoomEntry() { |
942 next_state_ = STATE_DOOM_ENTRY_COMPLETE; | 971 next_state_ = STATE_DOOM_ENTRY_COMPLETE; |
943 cache_pending_ = true; | 972 cache_pending_ = true; |
| 973 if (first_cache_access_since_.is_null()) |
| 974 first_cache_access_since_ = TimeTicks::Now(); |
944 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY); | 975 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY); |
945 ReportCacheActionStart(); | 976 ReportCacheActionStart(); |
946 return cache_->DoomEntry(cache_key_, this); | 977 return cache_->DoomEntry(cache_key_, this); |
947 } | 978 } |
948 | 979 |
949 int HttpCache::Transaction::DoDoomEntryComplete(int result) { | 980 int HttpCache::Transaction::DoDoomEntryComplete(int result) { |
950 ReportCacheActionFinish(); | 981 ReportCacheActionFinish(); |
951 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY, result); | 982 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY, result); |
952 next_state_ = STATE_CREATE_ENTRY; | 983 next_state_ = STATE_CREATE_ENTRY; |
953 cache_pending_ = false; | 984 cache_pending_ = false; |
954 if (result == ERR_CACHE_RACE) | 985 if (result == ERR_CACHE_RACE) |
955 next_state_ = STATE_INIT_ENTRY; | 986 next_state_ = STATE_INIT_ENTRY; |
956 | |
957 return OK; | 987 return OK; |
958 } | 988 } |
959 | 989 |
960 int HttpCache::Transaction::DoAddToEntry() { | 990 int HttpCache::Transaction::DoAddToEntry() { |
961 DCHECK(new_entry_); | 991 DCHECK(new_entry_); |
962 cache_pending_ = true; | 992 cache_pending_ = true; |
963 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; | 993 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; |
964 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); | 994 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); |
965 DCHECK(entry_lock_waiting_since_.is_null()); | 995 DCHECK(entry_lock_waiting_since_.is_null()); |
966 entry_lock_waiting_since_ = TimeTicks::Now(); | 996 entry_lock_waiting_since_ = TimeTicks::Now(); |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 } | 1262 } |
1233 | 1263 |
1234 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { | 1264 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { |
1235 ReportCacheActionFinish(); | 1265 ReportCacheActionFinish(); |
1236 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1266 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
1237 if (result != io_buf_len_ || | 1267 if (result != io_buf_len_ || |
1238 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, | 1268 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, |
1239 &response_, &truncated_)) { | 1269 &response_, &truncated_)) { |
1240 return OnCacheReadError(result, true); | 1270 return OnCacheReadError(result, true); |
1241 } | 1271 } |
| 1272 bytes_read_from_cache_ += result; |
1242 | 1273 |
1243 // Some resources may have slipped in as truncated when they're not. | 1274 // Some resources may have slipped in as truncated when they're not. |
1244 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 1275 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
1245 if (response_.headers->GetContentLength() == current_size) | 1276 if (response_.headers->GetContentLength() == current_size) |
1246 truncated_ = false; | 1277 truncated_ = false; |
1247 | 1278 |
1248 // We now have access to the cache entry. | 1279 // We now have access to the cache entry. |
1249 // | 1280 // |
1250 // o if we are a reader for the transaction, then we can start reading the | 1281 // o if we are a reader for the transaction, then we can start reading the |
1251 // cache entry. | 1282 // cache entry. |
1252 // | 1283 // |
1253 // o if we can read or write, then we should check if the cache entry needs | 1284 // o if we can read or write, then we should check if the cache entry needs |
1254 // to be validated and then issue a network request if needed or just read | 1285 // to be validated and then issue a network request if needed or just read |
1255 // from the cache if the cache entry is already valid. | 1286 // from the cache if the cache entry is already valid. |
1256 // | 1287 // |
1257 // o if we are set to UPDATE, then we are handling an externally | 1288 // o if we are set to UPDATE, then we are handling an externally |
1258 // conditionalized request (if-modified-since / if-none-match). We check | 1289 // conditionalized request (if-modified-since / if-none-match). We check |
1259 // if the request headers define a validation request. | 1290 // if the request headers define a validation request. |
1260 // | 1291 // |
1261 switch (mode_) { | 1292 switch (mode_) { |
1262 case READ: | 1293 case READ: |
| 1294 UpdateTransactionPattern(PATTERN_ENTRY_USED); |
1263 result = BeginCacheRead(); | 1295 result = BeginCacheRead(); |
1264 break; | 1296 break; |
1265 case READ_WRITE: | 1297 case READ_WRITE: |
1266 result = BeginPartialCacheValidation(); | 1298 result = BeginPartialCacheValidation(); |
1267 break; | 1299 break; |
1268 case UPDATE: | 1300 case UPDATE: |
1269 result = BeginExternallyConditionalizedRequest(); | 1301 result = BeginExternallyConditionalizedRequest(); |
1270 break; | 1302 break; |
1271 case WRITE: | 1303 case WRITE: |
1272 default: | 1304 default: |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 return entry_->disk_entry->ReadData(kMetadataIndex, 0, response_.metadata, | 1358 return entry_->disk_entry->ReadData(kMetadataIndex, 0, response_.metadata, |
1327 response_.metadata->size(), | 1359 response_.metadata->size(), |
1328 io_callback_); | 1360 io_callback_); |
1329 } | 1361 } |
1330 | 1362 |
1331 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { | 1363 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { |
1332 ReportCacheActionFinish(); | 1364 ReportCacheActionFinish(); |
1333 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1365 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
1334 if (result != response_.metadata->size()) | 1366 if (result != response_.metadata->size()) |
1335 return OnCacheReadError(result, false); | 1367 return OnCacheReadError(result, false); |
1336 | |
1337 return OK; | 1368 return OK; |
1338 } | 1369 } |
1339 | 1370 |
1340 int HttpCache::Transaction::DoCacheQueryData() { | 1371 int HttpCache::Transaction::DoCacheQueryData() { |
1341 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; | 1372 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; |
1342 | 1373 |
1343 // Balanced in DoCacheQueryDataComplete. | 1374 // Balanced in DoCacheQueryDataComplete. |
1344 return entry_->disk_entry->ReadyForSparseIO(io_callback_); | 1375 return entry_->disk_entry->ReadyForSparseIO(io_callback_); |
1345 } | 1376 } |
1346 | 1377 |
(...skipping 24 matching lines...) Expand all Loading... |
1371 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { | 1402 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { |
1372 ReportCacheActionFinish(); | 1403 ReportCacheActionFinish(); |
1373 if (net_log_.IsLoggingAllEvents()) { | 1404 if (net_log_.IsLoggingAllEvents()) { |
1374 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, | 1405 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, |
1375 result); | 1406 result); |
1376 } | 1407 } |
1377 | 1408 |
1378 if (!cache_) | 1409 if (!cache_) |
1379 return ERR_UNEXPECTED; | 1410 return ERR_UNEXPECTED; |
1380 | 1411 |
1381 if (partial_.get()) | 1412 if (partial_.get()) { |
| 1413 // Partial requests are confusing to report in histograms because they may |
| 1414 // have multiple underlying requests. |
| 1415 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
1382 return DoPartialCacheReadCompleted(result); | 1416 return DoPartialCacheReadCompleted(result); |
| 1417 } |
1383 | 1418 |
1384 if (result > 0) { | 1419 if (result > 0) { |
1385 read_offset_ += result; | 1420 read_offset_ += result; |
| 1421 bytes_read_from_cache_ += result; |
1386 } else if (result == 0) { // End of file. | 1422 } else if (result == 0) { // End of file. |
| 1423 RecordHistograms(); |
1387 cache_->DoneReadingFromEntry(entry_, this); | 1424 cache_->DoneReadingFromEntry(entry_, this); |
1388 entry_ = NULL; | 1425 entry_ = NULL; |
1389 } else { | 1426 } else { |
1390 return OnCacheReadError(result, false); | 1427 return OnCacheReadError(result, false); |
1391 } | 1428 } |
1392 return result; | 1429 return result; |
1393 } | 1430 } |
1394 | 1431 |
1395 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { | 1432 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { |
1396 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; | 1433 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1530 | 1567 |
1531 // If there is more than one validation header, we can't treat this request as | 1568 // If there is more than one validation header, we can't treat this request as |
1532 // a cache validation, since we don't know for sure which header the server | 1569 // a cache validation, since we don't know for sure which header the server |
1533 // will give us a response for (and they could be contradictory). | 1570 // will give us a response for (and they could be contradictory). |
1534 if (external_validation_error) { | 1571 if (external_validation_error) { |
1535 LOG(WARNING) << "Multiple or malformed validation headers found."; | 1572 LOG(WARNING) << "Multiple or malformed validation headers found."; |
1536 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 1573 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
1537 } | 1574 } |
1538 | 1575 |
1539 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { | 1576 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { |
| 1577 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
1540 partial_.reset(new PartialData); | 1578 partial_.reset(new PartialData); |
1541 if (request_->method == "GET" && partial_->Init(request_->extra_headers)) { | 1579 if (request_->method == "GET" && partial_->Init(request_->extra_headers)) { |
1542 // We will be modifying the actual range requested to the server, so | 1580 // We will be modifying the actual range requested to the server, so |
1543 // let's remove the header here. | 1581 // let's remove the header here. |
1544 custom_request_.reset(new HttpRequestInfo(*request_)); | 1582 custom_request_.reset(new HttpRequestInfo(*request_)); |
1545 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); | 1583 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); |
1546 request_ = custom_request_.get(); | 1584 request_ = custom_request_.get(); |
1547 partial_->SetHeaders(custom_request_->extra_headers); | 1585 partial_->SetHeaders(custom_request_->extra_headers); |
1548 } else { | 1586 } else { |
1549 // The range is invalid or we cannot handle it properly. | 1587 // The range is invalid or we cannot handle it properly. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 | 1639 |
1602 return OK; | 1640 return OK; |
1603 } | 1641 } |
1604 | 1642 |
1605 int HttpCache::Transaction::BeginCacheValidation() { | 1643 int HttpCache::Transaction::BeginCacheValidation() { |
1606 DCHECK(mode_ == READ_WRITE); | 1644 DCHECK(mode_ == READ_WRITE); |
1607 | 1645 |
1608 bool skip_validation = effective_load_flags_ & LOAD_PREFERRING_CACHE || | 1646 bool skip_validation = effective_load_flags_ & LOAD_PREFERRING_CACHE || |
1609 !RequiresValidation(); | 1647 !RequiresValidation(); |
1610 | 1648 |
1611 if (truncated_) | 1649 if (truncated_) { |
| 1650 // Truncated entries can cause partial gets, so we shouldn't record this |
| 1651 // load in histograms. |
| 1652 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
1612 skip_validation = !partial_->initial_validation(); | 1653 skip_validation = !partial_->initial_validation(); |
| 1654 } |
1613 | 1655 |
1614 if (partial_.get() && (is_sparse_ || truncated_) && | 1656 if (partial_.get() && (is_sparse_ || truncated_) && |
1615 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 1657 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
1616 // Force revalidation for sparse or truncated entries. Note that we don't | 1658 // Force revalidation for sparse or truncated entries. Note that we don't |
1617 // want to ignore the regular validation logic just because a byte range was | 1659 // want to ignore the regular validation logic just because a byte range was |
1618 // part of the request. | 1660 // part of the request. |
1619 skip_validation = false; | 1661 skip_validation = false; |
1620 } | 1662 } |
1621 | 1663 |
1622 if (skip_validation) { | 1664 if (skip_validation) { |
| 1665 UpdateTransactionPattern(PATTERN_ENTRY_USED); |
1623 if (partial_.get()) { | 1666 if (partial_.get()) { |
1624 if (truncated_ || is_sparse_ || !invalid_range_) { | 1667 if (truncated_ || is_sparse_ || !invalid_range_) { |
1625 // We are going to return the saved response headers to the caller, so | 1668 // We are going to return the saved response headers to the caller, so |
1626 // we may need to adjust them first. | 1669 // we may need to adjust them first. |
1627 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1670 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
1628 return OK; | 1671 return OK; |
1629 } else { | 1672 } else { |
1630 partial_.reset(); | 1673 partial_.reset(); |
1631 } | 1674 } |
1632 } | 1675 } |
1633 cache_->ConvertWriterToReader(entry_); | 1676 cache_->ConvertWriterToReader(entry_); |
1634 mode_ = READ; | 1677 mode_ = READ; |
1635 | 1678 |
1636 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1679 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
1637 next_state_ = STATE_CACHE_READ_METADATA; | 1680 next_state_ = STATE_CACHE_READ_METADATA; |
1638 } else { | 1681 } else { |
1639 // Make the network request conditional, to see if we may reuse our cached | 1682 // Make the network request conditional, to see if we may reuse our cached |
1640 // response. If we cannot do so, then we just resort to a normal fetch. | 1683 // response. If we cannot do so, then we just resort to a normal fetch. |
1641 // Our mode remains READ_WRITE for a conditional request. We'll switch to | 1684 // Our mode remains READ_WRITE for a conditional request. We'll switch to |
1642 // either READ or WRITE mode once we hear back from the server. | 1685 // either READ or WRITE mode once we hear back from the server. |
1643 if (!ConditionalizeRequest()) { | 1686 if (!ConditionalizeRequest()) { |
| 1687 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
1644 if (partial_.get()) | 1688 if (partial_.get()) |
1645 return DoRestartPartialRequest(); | 1689 return DoRestartPartialRequest(); |
1646 | 1690 |
1647 DCHECK_NE(206, response_.headers->response_code()); | 1691 DCHECK_NE(206, response_.headers->response_code()); |
1648 mode_ = WRITE; | 1692 mode_ = WRITE; |
1649 } | 1693 } |
1650 next_state_ = STATE_SEND_REQUEST; | 1694 next_state_ = STATE_SEND_REQUEST; |
1651 } | 1695 } |
1652 return OK; | 1696 return OK; |
1653 } | 1697 } |
1654 | 1698 |
1655 int HttpCache::Transaction::BeginPartialCacheValidation() { | 1699 int HttpCache::Transaction::BeginPartialCacheValidation() { |
1656 DCHECK(mode_ == READ_WRITE); | 1700 DCHECK(mode_ == READ_WRITE); |
1657 | 1701 |
1658 if (response_.headers->response_code() != 206 && !partial_.get() && | 1702 if (response_.headers->response_code() != 206 && !partial_.get() && |
1659 !truncated_) | 1703 !truncated_) |
1660 return BeginCacheValidation(); | 1704 return BeginCacheValidation(); |
1661 | 1705 |
| 1706 // Partial requests should not be recorded in histograms. |
| 1707 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
1662 if (range_requested_) { | 1708 if (range_requested_) { |
1663 next_state_ = STATE_CACHE_QUERY_DATA; | 1709 next_state_ = STATE_CACHE_QUERY_DATA; |
1664 return OK; | 1710 return OK; |
1665 } | 1711 } |
1666 // The request is not for a range, but we have stored just ranges. | 1712 // The request is not for a range, but we have stored just ranges. |
1667 partial_.reset(new PartialData()); | 1713 partial_.reset(new PartialData()); |
1668 partial_->SetHeaders(request_->extra_headers); | 1714 partial_->SetHeaders(request_->extra_headers); |
1669 if (!custom_request_.get()) { | 1715 if (!custom_request_.get()) { |
1670 custom_request_.reset(new HttpRequestInfo(*request_)); | 1716 custom_request_.reset(new HttpRequestInfo(*request_)); |
1671 request_ = custom_request_.get(); | 1717 request_ = custom_request_.get(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1706 std::string validator; | 1752 std::string validator; |
1707 response_.headers->EnumerateHeader( | 1753 response_.headers->EnumerateHeader( |
1708 NULL, | 1754 NULL, |
1709 kValidationHeaders[i].related_response_header_name, | 1755 kValidationHeaders[i].related_response_header_name, |
1710 &validator); | 1756 &validator); |
1711 | 1757 |
1712 if (response_.headers->response_code() != 200 || truncated_ || | 1758 if (response_.headers->response_code() != 200 || truncated_ || |
1713 validator.empty() || validator != external_validation_.values[i]) { | 1759 validator.empty() || validator != external_validation_.values[i]) { |
1714 // The externally conditionalized request is not a validation request | 1760 // The externally conditionalized request is not a validation request |
1715 // for our existing cache entry. Proceed with caching disabled. | 1761 // for our existing cache entry. Proceed with caching disabled. |
| 1762 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
1716 DoneWritingToEntry(true); | 1763 DoneWritingToEntry(true); |
1717 } | 1764 } |
1718 } | 1765 } |
1719 | 1766 |
1720 next_state_ = STATE_SEND_REQUEST; | 1767 next_state_ = STATE_SEND_REQUEST; |
1721 return OK; | 1768 return OK; |
1722 } | 1769 } |
1723 | 1770 |
1724 int HttpCache::Transaction::RestartNetworkRequest() { | 1771 int HttpCache::Transaction::RestartNetworkRequest() { |
1725 DCHECK(mode_ & WRITE || mode_ == NONE); | 1772 DCHECK(mode_ & WRITE || mode_ == NONE); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1939 } | 1986 } |
1940 | 1987 |
1941 // 304 is not expected here, but we'll spare the entry (unless it was | 1988 // 304 is not expected here, but we'll spare the entry (unless it was |
1942 // truncated). | 1989 // truncated). |
1943 if (truncated_) | 1990 if (truncated_) |
1944 failure = true; | 1991 failure = true; |
1945 } | 1992 } |
1946 | 1993 |
1947 if (failure) { | 1994 if (failure) { |
1948 // We cannot truncate this entry, it has to be deleted. | 1995 // We cannot truncate this entry, it has to be deleted. |
| 1996 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
1949 DoomPartialEntry(false); | 1997 DoomPartialEntry(false); |
1950 mode_ = NONE; | 1998 mode_ = NONE; |
1951 if (!reading_ && !partial_->IsLastRange()) { | 1999 if (!reading_ && !partial_->IsLastRange()) { |
1952 // We'll attempt to issue another network request, this time without us | 2000 // We'll attempt to issue another network request, this time without us |
1953 // messing up the headers. | 2001 // messing up the headers. |
1954 partial_->RestoreHeaders(&custom_request_->extra_headers); | 2002 partial_->RestoreHeaders(&custom_request_->extra_headers); |
1955 partial_.reset(); | 2003 partial_.reset(); |
1956 truncated_ = false; | 2004 truncated_ = false; |
1957 return false; | 2005 return false; |
1958 } | 2006 } |
1959 LOG(WARNING) << "Failed to revalidate partial entry"; | 2007 LOG(WARNING) << "Failed to revalidate partial entry"; |
1960 partial_.reset(); | 2008 partial_.reset(); |
1961 return true; | 2009 return true; |
1962 } | 2010 } |
1963 | 2011 |
1964 IgnoreRangeRequest(); | 2012 IgnoreRangeRequest(); |
1965 return true; | 2013 return true; |
1966 } | 2014 } |
1967 | 2015 |
1968 void HttpCache::Transaction::IgnoreRangeRequest() { | 2016 void HttpCache::Transaction::IgnoreRangeRequest() { |
1969 // We have a problem. We may or may not be reading already (in which case we | 2017 // We have a problem. We may or may not be reading already (in which case we |
1970 // returned the headers), but we'll just pretend that this request is not | 2018 // returned the headers), but we'll just pretend that this request is not |
1971 // using the cache and see what happens. Most likely this is the first | 2019 // using the cache and see what happens. Most likely this is the first |
1972 // response from the server (it's not changing its mind midway, right?). | 2020 // response from the server (it's not changing its mind midway, right?). |
| 2021 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
1973 if (mode_ & WRITE) { | 2022 if (mode_ & WRITE) { |
1974 DoneWritingToEntry(mode_ != WRITE); | 2023 DoneWritingToEntry(mode_ != WRITE); |
1975 } else if (mode_ & READ && entry_) { | 2024 } else if (mode_ & READ && entry_) { |
1976 cache_->DoneReadingFromEntry(entry_, this); | 2025 cache_->DoneReadingFromEntry(entry_, this); |
1977 } | 2026 } |
1978 | 2027 |
1979 partial_.reset(NULL); | 2028 partial_.reset(NULL); |
1980 entry_ = NULL; | 2029 entry_ = NULL; |
1981 mode_ = NONE; | 2030 mode_ = NONE; |
1982 } | 2031 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2061 | 2110 |
2062 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2111 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
2063 return WriteToEntry(kResponseContentIndex, current_size, data, data_len, | 2112 return WriteToEntry(kResponseContentIndex, current_size, data, data_len, |
2064 callback); | 2113 callback); |
2065 } | 2114 } |
2066 | 2115 |
2067 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2116 void HttpCache::Transaction::DoneWritingToEntry(bool success) { |
2068 if (!entry_) | 2117 if (!entry_) |
2069 return; | 2118 return; |
2070 | 2119 |
2071 if (cache_->mode() == RECORD) | 2120 RecordHistograms(); |
2072 DVLOG(1) << "Recorded: " << request_->method << request_->url | |
2073 << " status: " << response_.headers->response_code(); | |
2074 | 2121 |
2075 cache_->DoneWritingToEntry(entry_, success); | 2122 cache_->DoneWritingToEntry(entry_, success); |
2076 entry_ = NULL; | 2123 entry_ = NULL; |
2077 mode_ = NONE; // switch to 'pass through' mode | 2124 mode_ = NONE; // switch to 'pass through' mode |
2078 } | 2125 } |
2079 | 2126 |
2080 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2127 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
2081 DLOG(ERROR) << "ReadData failed: " << result; | 2128 DLOG(ERROR) << "ReadData failed: " << result; |
2082 | 2129 |
2083 // Avoid using this entry in the future. | 2130 // Avoid using this entry in the future. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2178 void HttpCache::Transaction::ReportCacheActionStart() { | 2225 void HttpCache::Transaction::ReportCacheActionStart() { |
2179 if (transaction_delegate_) | 2226 if (transaction_delegate_) |
2180 transaction_delegate_->OnCacheActionStart(); | 2227 transaction_delegate_->OnCacheActionStart(); |
2181 } | 2228 } |
2182 | 2229 |
2183 void HttpCache::Transaction::ReportCacheActionFinish() { | 2230 void HttpCache::Transaction::ReportCacheActionFinish() { |
2184 if (transaction_delegate_) | 2231 if (transaction_delegate_) |
2185 transaction_delegate_->OnCacheActionFinish(); | 2232 transaction_delegate_->OnCacheActionFinish(); |
2186 } | 2233 } |
2187 | 2234 |
| 2235 void HttpCache::Transaction::UpdateTransactionPattern( |
| 2236 TransactionPattern new_transaction_pattern) { |
| 2237 if (transaction_pattern_ == PATTERN_NOT_COVERED) |
| 2238 return; |
| 2239 DCHECK(transaction_pattern_ == PATTERN_UNDEFINED || |
| 2240 new_transaction_pattern == PATTERN_NOT_COVERED); |
| 2241 transaction_pattern_ = new_transaction_pattern; |
| 2242 } |
| 2243 |
| 2244 void HttpCache::Transaction::RecordHistograms() { |
| 2245 DCHECK_NE(PATTERN_UNDEFINED, transaction_pattern_); |
| 2246 if (!cache_ || !cache_->GetCurrentBackend() || |
| 2247 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || |
| 2248 cache_->mode() != NORMAL || request_->method != "GET") { |
| 2249 return; |
| 2250 } |
| 2251 UMA_HISTOGRAM_BOOLEAN("HttpCache.HasPattern", |
| 2252 transaction_pattern_ != PATTERN_NOT_COVERED); |
| 2253 if (transaction_pattern_ == PATTERN_NOT_COVERED) |
| 2254 return; |
| 2255 DCHECK(!range_requested_); |
| 2256 DCHECK(!first_cache_access_since_.is_null()); |
| 2257 |
| 2258 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2259 |
| 2260 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2261 |
| 2262 bool did_send_request = !send_request_since_.is_null(); |
| 2263 DCHECK( |
| 2264 (did_send_request && (transaction_pattern_ == PATTERN_ENTRY_NOT_CACHED || |
| 2265 transaction_pattern_ == PATTERN_ENTRY_VALIDATED || |
| 2266 transaction_pattern_ == PATTERN_ENTRY_UPDATED)) || |
| 2267 (!did_send_request && transaction_pattern_ == PATTERN_ENTRY_USED)); |
| 2268 |
| 2269 int resource_size; |
| 2270 if (transaction_pattern_ == PATTERN_ENTRY_NOT_CACHED || |
| 2271 transaction_pattern_ == PATTERN_ENTRY_UPDATED) { |
| 2272 resource_size = bytes_read_from_network_; |
| 2273 } else { |
| 2274 DCHECK(transaction_pattern_ == PATTERN_ENTRY_VALIDATED || |
| 2275 transaction_pattern_ == PATTERN_ENTRY_USED); |
| 2276 resource_size = bytes_read_from_cache_; |
| 2277 } |
| 2278 |
| 2279 bool is_small_resource = resource_size < kSmallResourceMaxBytes; |
| 2280 if (is_small_resource) |
| 2281 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SmallResource", total_time); |
| 2282 |
| 2283 if (!did_send_request) { |
| 2284 DCHECK(transaction_pattern_ == PATTERN_ENTRY_USED); |
| 2285 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); |
| 2286 if (is_small_resource) { |
| 2287 UMA_HISTOGRAM_TIMES( |
| 2288 "HttpCache.AccessToDone.Used.SmallResource", total_time); |
| 2289 } |
| 2290 return; |
| 2291 } |
| 2292 |
| 2293 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; |
| 2294 int before_send_percent = |
| 2295 total_time.ToInternalValue() == 0 ? 0 |
| 2296 : before_send_time * 100 / total_time; |
| 2297 DCHECK_LE(0, before_send_percent); |
| 2298 DCHECK_GE(100, before_send_percent); |
| 2299 |
| 2300 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); |
| 2301 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); |
| 2302 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_percent); |
| 2303 if (is_small_resource) { |
| 2304 UMA_HISTOGRAM_TIMES( |
| 2305 "HttpCache.AccessToDone.SentRequest.SmallResource", total_time); |
| 2306 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.SmallResource", before_send_time); |
| 2307 UMA_HISTOGRAM_PERCENTAGE( |
| 2308 "HttpCache.PercentBeforeSend.SmallResource", before_send_percent); |
| 2309 } |
| 2310 |
| 2311 // TODO(gavinp): Remove or minimize these histograms, particularly the ones |
| 2312 // below this comment after we have received initial data. |
| 2313 switch (transaction_pattern_) { |
| 2314 case PATTERN_ENTRY_NOT_CACHED: { |
| 2315 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); |
| 2316 UMA_HISTOGRAM_PERCENTAGE( |
| 2317 "HttpCache.PercentBeforeSend.NotCached", before_send_percent); |
| 2318 if (is_small_resource) { |
| 2319 UMA_HISTOGRAM_TIMES( |
| 2320 "HttpCache.BeforeSend.NotCached.SmallResource", before_send_time); |
| 2321 UMA_HISTOGRAM_PERCENTAGE( |
| 2322 "HttpCache.PercentBeforeSend.NotCached.SmallResource", |
| 2323 before_send_percent); |
| 2324 } |
| 2325 break; |
| 2326 } |
| 2327 case PATTERN_ENTRY_VALIDATED: { |
| 2328 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); |
| 2329 UMA_HISTOGRAM_PERCENTAGE( |
| 2330 "HttpCache.PercentBeforeSend.Validated", before_send_percent); |
| 2331 if (is_small_resource) { |
| 2332 UMA_HISTOGRAM_TIMES( |
| 2333 "HttpCache.BeforeSend.Validated.SmallResource", before_send_time); |
| 2334 UMA_HISTOGRAM_PERCENTAGE( |
| 2335 "HttpCache.PercentBeforeSend.Validated.SmallResource", |
| 2336 before_send_percent); |
| 2337 } |
| 2338 break; |
| 2339 } |
| 2340 case PATTERN_ENTRY_UPDATED: { |
| 2341 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); |
| 2342 UMA_HISTOGRAM_PERCENTAGE( |
| 2343 "HttpCache.PercentBeforeSend.Updated", before_send_percent); |
| 2344 if (is_small_resource) { |
| 2345 UMA_HISTOGRAM_TIMES( |
| 2346 "HttpCache.BeforeSend.Updated.SmallResource", before_send_time); |
| 2347 UMA_HISTOGRAM_PERCENTAGE( |
| 2348 "HttpCache.PercentBeforeSend.Updated.SmallResource", |
| 2349 before_send_percent); |
| 2350 } |
| 2351 break; |
| 2352 } |
| 2353 default: |
| 2354 NOTREACHED(); |
| 2355 } |
| 2356 } |
| 2357 |
2188 } // namespace net | 2358 } // namespace net |
OLD | NEW |