Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_cache_transaction.h" | 5 #include "net/http/http_cache_transaction.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 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 21 matching lines...) Expand all Loading... | |
| 32 #include "net/http/http_request_info.h" | 32 #include "net/http/http_request_info.h" |
| 33 #include "net/http/http_response_headers.h" | 33 #include "net/http/http_response_headers.h" |
| 34 #include "net/http/http_transaction.h" | 34 #include "net/http/http_transaction.h" |
| 35 #include "net/http/http_util.h" | 35 #include "net/http/http_util.h" |
| 36 #include "net/http/partial_data.h" | 36 #include "net/http/partial_data.h" |
| 37 | 37 |
| 38 using base::Time; | 38 using base::Time; |
| 39 using base::TimeDelta; | 39 using base::TimeDelta; |
| 40 using base::TimeTicks; | 40 using base::TimeTicks; |
| 41 | 41 |
| 42 namespace { | |
| 43 | |
| 44 // The cutoff for tagging small transactions in histograms; this size was chosen | |
| 45 // to cover resources likely to be received in a single TCP window. With an | |
| 46 // initial CWND of 10, and an MTU of 1500 bytes, with TCP and HTTP framing | |
| 47 // overhead this is a size relatively likely to take only one RTT. | |
| 48 const int kSmallResourceMaxBytes = 14 * 1024; | |
| 49 | |
| 50 } // namespace | |
| 51 | |
| 42 namespace net { | 52 namespace net { |
| 43 | 53 |
| 44 struct HeaderNameAndValue { | 54 struct HeaderNameAndValue { |
| 45 const char* name; | 55 const char* name; |
| 46 const char* value; | 56 const char* value; |
| 47 }; | 57 }; |
| 48 | 58 |
| 49 // If the request includes one of these request headers, then avoid caching | 59 // If the request includes one of these request headers, then avoid caching |
| 50 // to avoid getting confused. | 60 // to avoid getting confused. |
| 51 static const HeaderNameAndValue kPassThroughHeaders[] = { | 61 static const HeaderNameAndValue kPassThroughHeaders[] = { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 handling_206_(false), | 129 handling_206_(false), |
| 120 cache_pending_(false), | 130 cache_pending_(false), |
| 121 done_reading_(false), | 131 done_reading_(false), |
| 122 read_offset_(0), | 132 read_offset_(0), |
| 123 effective_load_flags_(0), | 133 effective_load_flags_(0), |
| 124 write_len_(0), | 134 write_len_(0), |
| 125 final_upload_progress_(0), | 135 final_upload_progress_(0), |
| 126 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 136 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 127 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( | 137 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( |
| 128 base::Bind(&Transaction::OnIOComplete, | 138 base::Bind(&Transaction::OnIOComplete, |
| 129 weak_factory_.GetWeakPtr()))) { | 139 weak_factory_.GetWeakPtr()))), |
| 140 transaction_pattern_(PATTERN_UNDEFINED), | |
| 141 bytes_read_from_cache_(0), | |
| 142 bytes_read_from_network_(0) { | |
| 130 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == | 143 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == |
| 131 arraysize(kValidationHeaders), | 144 arraysize(kValidationHeaders), |
| 132 Invalid_number_of_validation_headers); | 145 Invalid_number_of_validation_headers); |
| 133 } | 146 } |
| 134 | 147 |
| 135 HttpCache::Transaction::~Transaction() { | 148 HttpCache::Transaction::~Transaction() { |
| 136 // We may have to issue another IO, but we should never invoke the callback_ | 149 // We may have to issue another IO, but we should never invoke the callback_ |
| 137 // after this point. | 150 // after this point. |
| 138 callback_.Reset(); | 151 callback_.Reset(); |
| 139 | 152 |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 711 // This is only set if we have something to do with the response. | 724 // This is only set if we have something to do with the response. |
| 712 range_requested_ = (partial_.get() != NULL); | 725 range_requested_ = (partial_.get() != NULL); |
| 713 | 726 |
| 714 return OK; | 727 return OK; |
| 715 } | 728 } |
| 716 | 729 |
| 717 int HttpCache::Transaction::DoSendRequest() { | 730 int HttpCache::Transaction::DoSendRequest() { |
| 718 DCHECK(mode_ & WRITE || mode_ == NONE); | 731 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 719 DCHECK(!network_trans_.get()); | 732 DCHECK(!network_trans_.get()); |
| 720 | 733 |
| 734 send_request_since_ = TimeTicks::Now(); | |
| 735 | |
| 721 // Create a network transaction. | 736 // Create a network transaction. |
| 722 int rv = cache_->network_layer_->CreateTransaction(&network_trans_); | 737 int rv = cache_->network_layer_->CreateTransaction(&network_trans_); |
| 723 if (rv != OK) | 738 if (rv != OK) |
| 724 return rv; | 739 return rv; |
| 725 | 740 |
| 726 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 741 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
| 727 rv = network_trans_->Start(request_, io_callback_, net_log_); | 742 rv = network_trans_->Start(request_, io_callback_, net_log_); |
| 728 return rv; | 743 return rv; |
| 729 } | 744 } |
| 730 | 745 |
| 731 int HttpCache::Transaction::DoSendRequestComplete(int result) { | 746 int HttpCache::Transaction::DoSendRequestComplete(int result) { |
| 732 if (!cache_) | 747 if (!cache_) |
| 733 return ERR_UNEXPECTED; | 748 return ERR_UNEXPECTED; |
| 734 | 749 |
| 735 if (result == OK) { | 750 if (result == OK) { |
| 736 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 751 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
| 737 return OK; | 752 return OK; |
| 738 } | 753 } |
| 739 | 754 |
| 755 // Do not record requests that have network errors or restarts. | |
| 756 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
| 740 if (IsCertificateError(result)) { | 757 if (IsCertificateError(result)) { |
| 741 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 758 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
| 742 // If we get a certificate error, then there is a certificate in ssl_info, | 759 // If we get a certificate error, then there is a certificate in ssl_info, |
| 743 // so GetResponseInfo() should never return NULL here. | 760 // so GetResponseInfo() should never return NULL here. |
| 744 DCHECK(response); | 761 DCHECK(response); |
| 745 response_.ssl_info = response->ssl_info; | 762 response_.ssl_info = response->ssl_info; |
| 746 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 763 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 747 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 764 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
| 748 DCHECK(response); | 765 DCHECK(response); |
| 749 response_.cert_request_info = response->cert_request_info; | 766 response_.cert_request_info = response->cert_request_info; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 760 auth_response_ = *new_response; | 777 auth_response_ = *new_response; |
| 761 return OK; | 778 return OK; |
| 762 } | 779 } |
| 763 | 780 |
| 764 new_response_ = new_response; | 781 new_response_ = new_response; |
| 765 if (!ValidatePartialResponse() && !auth_response_.headers) { | 782 if (!ValidatePartialResponse() && !auth_response_.headers) { |
| 766 // Something went wrong with this request and we have to restart it. | 783 // Something went wrong with this request and we have to restart it. |
| 767 // If we have an authentication response, we are exposed to weird things | 784 // If we have an authentication response, we are exposed to weird things |
| 768 // hapenning if the user cancels the authentication before we receive | 785 // hapenning if the user cancels the authentication before we receive |
| 769 // the new response. | 786 // the new response. |
| 787 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
| 770 response_ = HttpResponseInfo(); | 788 response_ = HttpResponseInfo(); |
| 771 network_trans_.reset(); | 789 network_trans_.reset(); |
| 772 new_response_ = NULL; | 790 new_response_ = NULL; |
| 773 next_state_ = STATE_SEND_REQUEST; | 791 next_state_ = STATE_SEND_REQUEST; |
| 774 return OK; | 792 return OK; |
| 775 } | 793 } |
| 794 bytes_read_from_network_ += new_response_->headers->raw_headers().size(); | |
| 776 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { | 795 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { |
| 777 // We have stored the full entry, but it changed and the server is | 796 // We have stored the full entry, but it changed and the server is |
| 778 // sending a range. We have to delete the old entry. | 797 // sending a range. We have to delete the old entry. |
| 779 DoneWritingToEntry(false); | 798 DoneWritingToEntry(false); |
| 780 } | 799 } |
| 781 | |
| 782 if (new_response_->headers->response_code() == 416) { | 800 if (new_response_->headers->response_code() == 416) { |
| 783 DCHECK_EQ(NONE, mode_); | 801 DCHECK_EQ(NONE, mode_); |
| 784 response_ = *new_response_; | 802 response_ = *new_response_; |
| 785 return OK; | 803 return OK; |
| 786 } | 804 } |
| 787 | 805 |
| 806 DCHECK(mode_ != WRITE || transaction_pattern_ == PATTERN_ENTRY_NOT_CACHED || | |
| 807 transaction_pattern_ == PATTERN_NOT_COVERED); | |
|
rvargas (doing something else)
2012/07/31 17:43:57
What I really don't like about not handling WRITE
gavinp
2012/07/31 20:16:31
You're right about the state machine. My new uploa
| |
| 788 if (mode_ == WRITE && | 808 if (mode_ == WRITE && |
| 789 (request_->method == "PUT" || request_->method == "DELETE")) { | 809 (request_->method == "PUT" || request_->method == "DELETE")) { |
| 790 if (new_response->headers->response_code() == 200) { | 810 if (new_response->headers->response_code() == 200) { |
| 791 int ret = cache_->DoomEntry(cache_key_, NULL); | 811 int ret = cache_->DoomEntry(cache_key_, NULL); |
| 792 DCHECK_EQ(OK, ret); | 812 DCHECK_EQ(OK, ret); |
| 793 } | 813 } |
| 794 mode_ = NONE; | 814 mode_ = NONE; |
| 795 } | 815 } |
| 796 | 816 |
| 797 // Are we expecting a response to a conditional query? | 817 // Are we expecting a response to a conditional query? |
| 798 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 818 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
| 799 if (new_response->headers->response_code() == 304 || handling_206_) { | 819 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 820 UpdateTransactionPattern(PATTERN_ENTRY_VALIDATED); | |
| 800 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 821 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
| 801 return OK; | 822 return OK; |
| 802 } | 823 } |
| 824 UpdateTransactionPattern(PATTERN_ENTRY_UPDATED); | |
| 803 mode_ = WRITE; | 825 mode_ = WRITE; |
| 804 } | 826 } |
| 805 | 827 |
| 806 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; | 828 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; |
| 807 return OK; | 829 return OK; |
| 808 } | 830 } |
| 809 | 831 |
| 810 int HttpCache::Transaction::DoNetworkRead() { | 832 int HttpCache::Transaction::DoNetworkRead() { |
| 811 next_state_ = STATE_NETWORK_READ_COMPLETE; | 833 next_state_ = STATE_NETWORK_READ_COMPLETE; |
| 812 return network_trans_->Read(read_buf_, io_buf_len_, io_callback_); | 834 return network_trans_->Read(read_buf_, io_buf_len_, io_callback_); |
| 813 } | 835 } |
| 814 | 836 |
| 815 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 837 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| 816 DCHECK(mode_ & WRITE || mode_ == NONE); | 838 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 817 | 839 |
| 818 if (!cache_) | 840 if (!cache_) |
| 819 return ERR_UNEXPECTED; | 841 return ERR_UNEXPECTED; |
| 820 | 842 |
| 843 if (result > 0) | |
| 844 bytes_read_from_network_ += result; | |
| 845 | |
| 821 // If there is an error or we aren't saving the data, we are done; just wait | 846 // If there is an error or we aren't saving the data, we are done; just wait |
| 822 // until the destructor runs to see if we can keep the data. | 847 // until the destructor runs to see if we can keep the data. |
| 823 if (mode_ == NONE || result < 0) | 848 if (mode_ == NONE || result < 0) |
| 824 return result; | 849 return result; |
| 825 | 850 |
| 826 next_state_ = STATE_CACHE_WRITE_DATA; | 851 next_state_ = STATE_CACHE_WRITE_DATA; |
| 827 return result; | 852 return result; |
| 828 } | 853 } |
| 829 | 854 |
| 830 int HttpCache::Transaction::DoInitEntry() { | 855 int HttpCache::Transaction::DoInitEntry() { |
| 831 DCHECK(!new_entry_); | 856 DCHECK(!new_entry_); |
| 832 | 857 |
| 833 if (!cache_) | 858 if (!cache_) |
| 834 return ERR_UNEXPECTED; | 859 return ERR_UNEXPECTED; |
| 835 | 860 |
| 836 if (mode_ == WRITE) { | 861 if (mode_ == WRITE) { |
| 837 next_state_ = STATE_DOOM_ENTRY; | 862 next_state_ = STATE_DOOM_ENTRY; |
| 838 return OK; | 863 return OK; |
| 839 } | 864 } |
| 840 | 865 |
| 841 next_state_ = STATE_OPEN_ENTRY; | 866 next_state_ = STATE_OPEN_ENTRY; |
| 842 return OK; | 867 return OK; |
| 843 } | 868 } |
| 844 | 869 |
| 845 int HttpCache::Transaction::DoOpenEntry() { | 870 int HttpCache::Transaction::DoOpenEntry() { |
| 846 DCHECK(!new_entry_); | 871 DCHECK(!new_entry_); |
| 847 next_state_ = STATE_OPEN_ENTRY_COMPLETE; | 872 next_state_ = STATE_OPEN_ENTRY_COMPLETE; |
| 848 cache_pending_ = true; | 873 cache_pending_ = true; |
| 849 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); | 874 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); |
| 875 open_entry_since_ = TimeTicks::Now(); | |
| 850 return cache_->OpenEntry(cache_key_, &new_entry_, this); | 876 return cache_->OpenEntry(cache_key_, &new_entry_, this); |
| 851 } | 877 } |
| 852 | 878 |
| 853 int HttpCache::Transaction::DoOpenEntryComplete(int result) { | 879 int HttpCache::Transaction::DoOpenEntryComplete(int result) { |
| 854 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is | 880 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is |
| 855 // OK, otherwise the cache will end up with an active entry without any | 881 // OK, otherwise the cache will end up with an active entry without any |
| 856 // transaction attached. | 882 // transaction attached. |
| 857 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); | 883 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); |
| 858 cache_pending_ = false; | 884 cache_pending_ = false; |
| 859 if (result == OK) { | 885 if (result == OK) { |
| 860 next_state_ = STATE_ADD_TO_ENTRY; | 886 next_state_ = STATE_ADD_TO_ENTRY; |
| 861 return OK; | 887 return OK; |
| 862 } | 888 } |
| 863 | 889 |
| 864 if (result == ERR_CACHE_RACE) { | 890 if (result == ERR_CACHE_RACE) { |
| 865 next_state_ = STATE_INIT_ENTRY; | 891 next_state_ = STATE_INIT_ENTRY; |
| 866 return OK; | 892 return OK; |
| 867 } | 893 } |
| 868 | 894 |
| 895 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED); | |
| 869 if (request_->method == "PUT" || request_->method == "DELETE") { | 896 if (request_->method == "PUT" || request_->method == "DELETE") { |
| 870 DCHECK(mode_ == READ_WRITE || mode_ == WRITE); | 897 DCHECK(mode_ == READ_WRITE || mode_ == WRITE); |
| 871 mode_ = NONE; | 898 mode_ = NONE; |
| 872 next_state_ = STATE_SEND_REQUEST; | 899 next_state_ = STATE_SEND_REQUEST; |
| 873 return OK; | 900 return OK; |
| 874 } | 901 } |
| 875 | 902 |
| 876 if (mode_ == READ_WRITE) { | 903 if (mode_ == READ_WRITE) { |
| 877 mode_ = WRITE; | 904 mode_ = WRITE; |
| 878 next_state_ = STATE_CREATE_ENTRY; | 905 next_state_ = STATE_CREATE_ENTRY; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 924 if (partial_.get()) | 951 if (partial_.get()) |
| 925 partial_->RestoreHeaders(&custom_request_->extra_headers); | 952 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 926 next_state_ = STATE_SEND_REQUEST; | 953 next_state_ = STATE_SEND_REQUEST; |
| 927 } | 954 } |
| 928 return OK; | 955 return OK; |
| 929 } | 956 } |
| 930 | 957 |
| 931 int HttpCache::Transaction::DoDoomEntry() { | 958 int HttpCache::Transaction::DoDoomEntry() { |
| 932 next_state_ = STATE_DOOM_ENTRY_COMPLETE; | 959 next_state_ = STATE_DOOM_ENTRY_COMPLETE; |
| 933 cache_pending_ = true; | 960 cache_pending_ = true; |
| 961 doom_entry_since_ = TimeTicks::Now(); | |
| 934 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY); | 962 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY); |
| 935 return cache_->DoomEntry(cache_key_, this); | 963 return cache_->DoomEntry(cache_key_, this); |
| 936 } | 964 } |
| 937 | 965 |
| 938 int HttpCache::Transaction::DoDoomEntryComplete(int result) { | 966 int HttpCache::Transaction::DoDoomEntryComplete(int result) { |
| 939 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY, result); | 967 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY, result); |
| 940 next_state_ = STATE_CREATE_ENTRY; | 968 next_state_ = STATE_CREATE_ENTRY; |
| 941 cache_pending_ = false; | 969 cache_pending_ = false; |
| 942 if (result == ERR_CACHE_RACE) | 970 if (result == ERR_CACHE_RACE) |
| 943 next_state_ = STATE_INIT_ENTRY; | 971 next_state_ = STATE_INIT_ENTRY; |
| 944 | 972 else |
| 973 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED); | |
| 945 return OK; | 974 return OK; |
| 946 } | 975 } |
| 947 | 976 |
| 948 int HttpCache::Transaction::DoAddToEntry() { | 977 int HttpCache::Transaction::DoAddToEntry() { |
| 949 DCHECK(new_entry_); | 978 DCHECK(new_entry_); |
| 950 cache_pending_ = true; | 979 cache_pending_ = true; |
| 951 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; | 980 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; |
| 952 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); | 981 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); |
| 953 DCHECK(entry_lock_waiting_since_.is_null()); | 982 DCHECK(entry_lock_waiting_since_.is_null()); |
| 954 entry_lock_waiting_since_ = TimeTicks::Now(); | 983 entry_lock_waiting_since_ = TimeTicks::Now(); |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1211 io_buf_len_, io_callback_); | 1240 io_buf_len_, io_callback_); |
| 1212 } | 1241 } |
| 1213 | 1242 |
| 1214 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { | 1243 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { |
| 1215 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1244 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
| 1216 if (result != io_buf_len_ || | 1245 if (result != io_buf_len_ || |
| 1217 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, | 1246 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, |
| 1218 &response_, &truncated_)) { | 1247 &response_, &truncated_)) { |
| 1219 return OnCacheReadError(result, true); | 1248 return OnCacheReadError(result, true); |
| 1220 } | 1249 } |
| 1250 bytes_read_from_cache_ += result; | |
| 1221 | 1251 |
| 1222 // Some resources may have slipped in as truncated when they're not. | 1252 // Some resources may have slipped in as truncated when they're not. |
| 1223 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 1253 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1224 if (response_.headers->GetContentLength() == current_size) | 1254 if (response_.headers->GetContentLength() == current_size) |
| 1225 truncated_ = false; | 1255 truncated_ = false; |
| 1226 | 1256 |
| 1227 // We now have access to the cache entry. | 1257 // We now have access to the cache entry. |
| 1228 // | 1258 // |
| 1229 // o if we are a reader for the transaction, then we can start reading the | 1259 // o if we are a reader for the transaction, then we can start reading the |
| 1230 // cache entry. | 1260 // cache entry. |
| 1231 // | 1261 // |
| 1232 // o if we can read or write, then we should check if the cache entry needs | 1262 // o if we can read or write, then we should check if the cache entry needs |
| 1233 // to be validated and then issue a network request if needed or just read | 1263 // to be validated and then issue a network request if needed or just read |
| 1234 // from the cache if the cache entry is already valid. | 1264 // from the cache if the cache entry is already valid. |
| 1235 // | 1265 // |
| 1236 // o if we are set to UPDATE, then we are handling an externally | 1266 // o if we are set to UPDATE, then we are handling an externally |
| 1237 // conditionalized request (if-modified-since / if-none-match). We check | 1267 // conditionalized request (if-modified-since / if-none-match). We check |
| 1238 // if the request headers define a validation request. | 1268 // if the request headers define a validation request. |
| 1239 // | 1269 // |
| 1240 switch (mode_) { | 1270 switch (mode_) { |
| 1241 case READ: | 1271 case READ: |
| 1272 UpdateTransactionPattern(PATTERN_ENTRY_USED); | |
| 1242 result = BeginCacheRead(); | 1273 result = BeginCacheRead(); |
| 1243 break; | 1274 break; |
| 1244 case READ_WRITE: | 1275 case READ_WRITE: |
| 1245 result = BeginPartialCacheValidation(); | 1276 result = BeginPartialCacheValidation(); |
| 1246 break; | 1277 break; |
| 1247 case UPDATE: | 1278 case UPDATE: |
| 1248 result = BeginExternallyConditionalizedRequest(); | 1279 result = BeginExternallyConditionalizedRequest(); |
| 1249 break; | 1280 break; |
| 1250 case WRITE: | 1281 case WRITE: |
| 1251 default: | 1282 default: |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1296 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); | 1327 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
| 1297 return entry_->disk_entry->ReadData(kMetadataIndex, 0, response_.metadata, | 1328 return entry_->disk_entry->ReadData(kMetadataIndex, 0, response_.metadata, |
| 1298 response_.metadata->size(), | 1329 response_.metadata->size(), |
| 1299 io_callback_); | 1330 io_callback_); |
| 1300 } | 1331 } |
| 1301 | 1332 |
| 1302 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { | 1333 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { |
| 1303 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1334 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
| 1304 if (result != response_.metadata->size()) | 1335 if (result != response_.metadata->size()) |
| 1305 return OnCacheReadError(result, false); | 1336 return OnCacheReadError(result, false); |
| 1306 | |
| 1307 return OK; | 1337 return OK; |
| 1308 } | 1338 } |
| 1309 | 1339 |
| 1310 int HttpCache::Transaction::DoCacheQueryData() { | 1340 int HttpCache::Transaction::DoCacheQueryData() { |
| 1311 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; | 1341 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; |
| 1312 | 1342 |
| 1313 // Balanced in DoCacheQueryDataComplete. | 1343 // Balanced in DoCacheQueryDataComplete. |
| 1314 return entry_->disk_entry->ReadyForSparseIO(io_callback_); | 1344 return entry_->disk_entry->ReadyForSparseIO(io_callback_); |
| 1315 } | 1345 } |
| 1316 | 1346 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1339 | 1369 |
| 1340 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { | 1370 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { |
| 1341 if (net_log_.IsLoggingAllEvents()) { | 1371 if (net_log_.IsLoggingAllEvents()) { |
| 1342 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, | 1372 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, |
| 1343 result); | 1373 result); |
| 1344 } | 1374 } |
| 1345 | 1375 |
| 1346 if (!cache_) | 1376 if (!cache_) |
| 1347 return ERR_UNEXPECTED; | 1377 return ERR_UNEXPECTED; |
| 1348 | 1378 |
| 1349 if (partial_.get()) | 1379 if (partial_.get()) { |
| 1380 // Partial requests are confusing to report in histograms because they may | |
| 1381 // have multiple underlying requests. | |
| 1382 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
| 1350 return DoPartialCacheReadCompleted(result); | 1383 return DoPartialCacheReadCompleted(result); |
| 1384 } | |
| 1351 | 1385 |
| 1352 if (result > 0) { | 1386 if (result > 0) { |
| 1353 read_offset_ += result; | 1387 read_offset_ += result; |
| 1388 bytes_read_from_cache_ += result; | |
| 1354 } else if (result == 0) { // End of file. | 1389 } else if (result == 0) { // End of file. |
| 1390 RecordHistograms(); | |
| 1355 cache_->DoneReadingFromEntry(entry_, this); | 1391 cache_->DoneReadingFromEntry(entry_, this); |
| 1356 entry_ = NULL; | 1392 entry_ = NULL; |
| 1357 } else { | 1393 } else { |
| 1358 return OnCacheReadError(result, false); | 1394 return OnCacheReadError(result, false); |
| 1359 } | 1395 } |
| 1360 return result; | 1396 return result; |
| 1361 } | 1397 } |
| 1362 | 1398 |
| 1363 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { | 1399 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { |
| 1364 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; | 1400 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1492 | 1528 |
| 1493 // If there is more than one validation header, we can't treat this request as | 1529 // If there is more than one validation header, we can't treat this request as |
| 1494 // a cache validation, since we don't know for sure which header the server | 1530 // a cache validation, since we don't know for sure which header the server |
| 1495 // will give us a response for (and they could be contradictory). | 1531 // will give us a response for (and they could be contradictory). |
| 1496 if (external_validation_error) { | 1532 if (external_validation_error) { |
| 1497 LOG(WARNING) << "Multiple or malformed validation headers found."; | 1533 LOG(WARNING) << "Multiple or malformed validation headers found."; |
| 1498 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 1534 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| 1499 } | 1535 } |
| 1500 | 1536 |
| 1501 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { | 1537 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { |
| 1538 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
| 1502 partial_.reset(new PartialData); | 1539 partial_.reset(new PartialData); |
| 1503 if (request_->method == "GET" && partial_->Init(request_->extra_headers)) { | 1540 if (request_->method == "GET" && partial_->Init(request_->extra_headers)) { |
| 1504 // We will be modifying the actual range requested to the server, so | 1541 // We will be modifying the actual range requested to the server, so |
| 1505 // let's remove the header here. | 1542 // let's remove the header here. |
| 1506 custom_request_.reset(new HttpRequestInfo(*request_)); | 1543 custom_request_.reset(new HttpRequestInfo(*request_)); |
| 1507 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); | 1544 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); |
| 1508 request_ = custom_request_.get(); | 1545 request_ = custom_request_.get(); |
| 1509 partial_->SetHeaders(custom_request_->extra_headers); | 1546 partial_->SetHeaders(custom_request_->extra_headers); |
| 1510 } else { | 1547 } else { |
| 1511 // The range is invalid or we cannot handle it properly. | 1548 // The range is invalid or we cannot handle it properly. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1563 | 1600 |
| 1564 return OK; | 1601 return OK; |
| 1565 } | 1602 } |
| 1566 | 1603 |
| 1567 int HttpCache::Transaction::BeginCacheValidation() { | 1604 int HttpCache::Transaction::BeginCacheValidation() { |
| 1568 DCHECK(mode_ == READ_WRITE); | 1605 DCHECK(mode_ == READ_WRITE); |
| 1569 | 1606 |
| 1570 bool skip_validation = effective_load_flags_ & LOAD_PREFERRING_CACHE || | 1607 bool skip_validation = effective_load_flags_ & LOAD_PREFERRING_CACHE || |
| 1571 !RequiresValidation(); | 1608 !RequiresValidation(); |
| 1572 | 1609 |
| 1573 if (truncated_) | 1610 if (truncated_) { |
| 1611 // Truncated entries can cause partial gets, so we shouldn't record this | |
| 1612 // load in histograms. | |
| 1613 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
| 1574 skip_validation = !partial_->initial_validation(); | 1614 skip_validation = !partial_->initial_validation(); |
| 1615 } | |
| 1575 | 1616 |
| 1576 if ((partial_.get() && !partial_->IsCurrentRangeCached()) || invalid_range_) | 1617 if ((partial_.get() && !partial_->IsCurrentRangeCached()) || invalid_range_) |
| 1577 skip_validation = false; | 1618 skip_validation = false; |
| 1578 | 1619 |
| 1579 if (skip_validation) { | 1620 if (skip_validation) { |
| 1621 UpdateTransactionPattern(PATTERN_ENTRY_USED); | |
| 1580 if (partial_.get()) { | 1622 if (partial_.get()) { |
| 1581 // We are going to return the saved response headers to the caller, so | 1623 // We are going to return the saved response headers to the caller, so |
| 1582 // we may need to adjust them first. | 1624 // we may need to adjust them first. |
| 1583 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1625 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1584 return OK; | 1626 return OK; |
| 1585 } | 1627 } |
| 1586 cache_->ConvertWriterToReader(entry_); | 1628 cache_->ConvertWriterToReader(entry_); |
| 1587 mode_ = READ; | 1629 mode_ = READ; |
| 1588 | 1630 |
| 1589 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1631 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 1590 next_state_ = STATE_CACHE_READ_METADATA; | 1632 next_state_ = STATE_CACHE_READ_METADATA; |
| 1591 } else { | 1633 } else { |
| 1592 // Make the network request conditional, to see if we may reuse our cached | 1634 // Make the network request conditional, to see if we may reuse our cached |
| 1593 // response. If we cannot do so, then we just resort to a normal fetch. | 1635 // response. If we cannot do so, then we just resort to a normal fetch. |
| 1594 // Our mode remains READ_WRITE for a conditional request. We'll switch to | 1636 // Our mode remains READ_WRITE for a conditional request. We'll switch to |
| 1595 // either READ or WRITE mode once we hear back from the server. | 1637 // either READ or WRITE mode once we hear back from the server. |
| 1596 if (!ConditionalizeRequest()) { | 1638 if (!ConditionalizeRequest()) { |
| 1639 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
| 1597 DCHECK(!partial_.get()); | 1640 DCHECK(!partial_.get()); |
| 1598 DCHECK_NE(206, response_.headers->response_code()); | 1641 DCHECK_NE(206, response_.headers->response_code()); |
| 1599 mode_ = WRITE; | 1642 mode_ = WRITE; |
| 1600 } | 1643 } |
| 1601 next_state_ = STATE_SEND_REQUEST; | 1644 next_state_ = STATE_SEND_REQUEST; |
| 1602 } | 1645 } |
| 1603 return OK; | 1646 return OK; |
| 1604 } | 1647 } |
| 1605 | 1648 |
| 1606 int HttpCache::Transaction::BeginPartialCacheValidation() { | 1649 int HttpCache::Transaction::BeginPartialCacheValidation() { |
| 1607 DCHECK(mode_ == READ_WRITE); | 1650 DCHECK(mode_ == READ_WRITE); |
| 1608 | 1651 |
| 1609 if (response_.headers->response_code() != 206 && !partial_.get() && | 1652 if (response_.headers->response_code() != 206 && !partial_.get() && |
| 1610 !truncated_) | 1653 !truncated_) |
| 1611 return BeginCacheValidation(); | 1654 return BeginCacheValidation(); |
| 1612 | 1655 |
| 1656 // Partial requests should not be recorded in histograms. | |
| 1657 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
| 1613 if (range_requested_) { | 1658 if (range_requested_) { |
| 1614 next_state_ = STATE_CACHE_QUERY_DATA; | 1659 next_state_ = STATE_CACHE_QUERY_DATA; |
| 1615 return OK; | 1660 return OK; |
| 1616 } | 1661 } |
| 1617 // The request is not for a range, but we have stored just ranges. | 1662 // The request is not for a range, but we have stored just ranges. |
| 1618 partial_.reset(new PartialData()); | 1663 partial_.reset(new PartialData()); |
| 1619 partial_->SetHeaders(request_->extra_headers); | 1664 partial_->SetHeaders(request_->extra_headers); |
| 1620 if (!custom_request_.get()) { | 1665 if (!custom_request_.get()) { |
| 1621 custom_request_.reset(new HttpRequestInfo(*request_)); | 1666 custom_request_.reset(new HttpRequestInfo(*request_)); |
| 1622 request_ = custom_request_.get(); | 1667 request_ = custom_request_.get(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1663 std::string validator; | 1708 std::string validator; |
| 1664 response_.headers->EnumerateHeader( | 1709 response_.headers->EnumerateHeader( |
| 1665 NULL, | 1710 NULL, |
| 1666 kValidationHeaders[i].related_response_header_name, | 1711 kValidationHeaders[i].related_response_header_name, |
| 1667 &validator); | 1712 &validator); |
| 1668 | 1713 |
| 1669 if (response_.headers->response_code() != 200 || truncated_ || | 1714 if (response_.headers->response_code() != 200 || truncated_ || |
| 1670 validator.empty() || validator != external_validation_.values[i]) { | 1715 validator.empty() || validator != external_validation_.values[i]) { |
| 1671 // The externally conditionalized request is not a validation request | 1716 // The externally conditionalized request is not a validation request |
| 1672 // for our existing cache entry. Proceed with caching disabled. | 1717 // for our existing cache entry. Proceed with caching disabled. |
| 1718 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
| 1673 DoneWritingToEntry(true); | 1719 DoneWritingToEntry(true); |
| 1674 } | 1720 } |
| 1675 } | 1721 } |
| 1676 | 1722 |
| 1677 next_state_ = STATE_SEND_REQUEST; | 1723 next_state_ = STATE_SEND_REQUEST; |
| 1678 return OK; | 1724 return OK; |
| 1679 } | 1725 } |
| 1680 | 1726 |
| 1681 int HttpCache::Transaction::RestartNetworkRequest() { | 1727 int HttpCache::Transaction::RestartNetworkRequest() { |
| 1682 DCHECK(mode_ & WRITE || mode_ == NONE); | 1728 DCHECK(mode_ & WRITE || mode_ == NONE); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1886 } | 1932 } |
| 1887 | 1933 |
| 1888 // 304 is not expected here, but we'll spare the entry (unless it was | 1934 // 304 is not expected here, but we'll spare the entry (unless it was |
| 1889 // truncated). | 1935 // truncated). |
| 1890 if (truncated_) | 1936 if (truncated_) |
| 1891 failure = true; | 1937 failure = true; |
| 1892 } | 1938 } |
| 1893 | 1939 |
| 1894 if (failure) { | 1940 if (failure) { |
| 1895 // We cannot truncate this entry, it has to be deleted. | 1941 // We cannot truncate this entry, it has to be deleted. |
| 1942 UpdateTransactionPattern(PATTERN_NOT_COVERED); | |
| 1896 DoomPartialEntry(false); | 1943 DoomPartialEntry(false); |
| 1897 mode_ = NONE; | 1944 mode_ = NONE; |
| 1898 if (!reading_ && !partial_->IsLastRange()) { | 1945 if (!reading_ && !partial_->IsLastRange()) { |
| 1899 // We'll attempt to issue another network request, this time without us | 1946 // We'll attempt to issue another network request, this time without us |
| 1900 // messing up the headers. | 1947 // messing up the headers. |
| 1901 partial_->RestoreHeaders(&custom_request_->extra_headers); | 1948 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 1902 partial_.reset(); | 1949 partial_.reset(); |
| 1903 truncated_ = false; | 1950 truncated_ = false; |
| 1904 return false; | 1951 return false; |
| 1905 } | 1952 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2008 | 2055 |
| 2009 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2056 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 2010 return WriteToEntry(kResponseContentIndex, current_size, data, data_len, | 2057 return WriteToEntry(kResponseContentIndex, current_size, data, data_len, |
| 2011 callback); | 2058 callback); |
| 2012 } | 2059 } |
| 2013 | 2060 |
| 2014 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2061 void HttpCache::Transaction::DoneWritingToEntry(bool success) { |
| 2015 if (!entry_) | 2062 if (!entry_) |
| 2016 return; | 2063 return; |
| 2017 | 2064 |
| 2018 if (cache_->mode() == RECORD) | 2065 RecordHistograms(); |
| 2019 DVLOG(1) << "Recorded: " << request_->method << request_->url | |
| 2020 << " status: " << response_.headers->response_code(); | |
| 2021 | 2066 |
| 2022 cache_->DoneWritingToEntry(entry_, success); | 2067 cache_->DoneWritingToEntry(entry_, success); |
| 2023 entry_ = NULL; | 2068 entry_ = NULL; |
| 2024 mode_ = NONE; // switch to 'pass through' mode | 2069 mode_ = NONE; // switch to 'pass through' mode |
| 2025 } | 2070 } |
| 2026 | 2071 |
| 2027 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2072 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
| 2028 DLOG(ERROR) << "ReadData failed: " << result; | 2073 DLOG(ERROR) << "ReadData failed: " << result; |
| 2029 | 2074 |
| 2030 // Avoid using this entry in the future. | 2075 // Avoid using this entry in the future. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2105 !response_.headers->HasStrongValidators()) | 2150 !response_.headers->HasStrongValidators()) |
| 2106 return false; | 2151 return false; |
| 2107 | 2152 |
| 2108 return true; | 2153 return true; |
| 2109 } | 2154 } |
| 2110 | 2155 |
| 2111 void HttpCache::Transaction::OnIOComplete(int result) { | 2156 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2112 DoLoop(result); | 2157 DoLoop(result); |
| 2113 } | 2158 } |
| 2114 | 2159 |
| 2160 void HttpCache::Transaction::UpdateTransactionPattern( | |
| 2161 TransactionPattern new_transaction_pattern) { | |
| 2162 if (transaction_pattern_ == PATTERN_NOT_COVERED) | |
| 2163 return; | |
| 2164 DCHECK(transaction_pattern_ == PATTERN_UNDEFINED || | |
| 2165 new_transaction_pattern == PATTERN_NOT_COVERED); | |
| 2166 transaction_pattern_ = new_transaction_pattern; | |
| 2167 } | |
| 2168 | |
| 2169 void HttpCache::Transaction::RecordHistograms() { | |
| 2170 DCHECK_NE(PATTERN_UNDEFINED, transaction_pattern_); | |
| 2171 if (!cache_ || !cache_->GetCurrentBackend() || | |
| 2172 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || | |
| 2173 cache_->mode() != NORMAL || request_->method != "GET") { | |
| 2174 return; | |
| 2175 } | |
| 2176 UMA_HISTOGRAM_BOOLEAN("HttpCache.HasPattern", | |
| 2177 transaction_pattern_ != PATTERN_NOT_COVERED); | |
| 2178 if (transaction_pattern_ == PATTERN_NOT_COVERED) | |
| 2179 return; | |
| 2180 DCHECK(!range_requested_); | |
| 2181 DCHECK(!open_entry_since_.is_null() || !doom_entry_since_.is_null()); | |
| 2182 | |
| 2183 TimeTicks start_time = !open_entry_since_.is_null() ? open_entry_since_ : | |
| 2184 doom_entry_since_; | |
| 2185 TimeDelta total_time = base::TimeTicks::Now() - start_time; | |
| 2186 | |
| 2187 UMA_HISTOGRAM_TIMES("HttpCache.TransactionTime", total_time); | |
| 2188 | |
| 2189 bool did_send_request = !send_request_since_.is_null(); | |
| 2190 DCHECK( | |
| 2191 (did_send_request && (transaction_pattern_ == PATTERN_ENTRY_NOT_CACHED || | |
| 2192 transaction_pattern_ == PATTERN_ENTRY_VALIDATED || | |
| 2193 transaction_pattern_ == PATTERN_ENTRY_UPDATED)) || | |
| 2194 (!did_send_request && transaction_pattern_ == PATTERN_ENTRY_USED)); | |
| 2195 | |
| 2196 int resource_size; | |
| 2197 if (transaction_pattern_ == PATTERN_ENTRY_NOT_CACHED || | |
| 2198 transaction_pattern_ == PATTERN_ENTRY_UPDATED) { | |
| 2199 resource_size = bytes_read_from_network_; | |
| 2200 } else { | |
| 2201 DCHECK(transaction_pattern_ == PATTERN_ENTRY_VALIDATED || | |
| 2202 transaction_pattern_ == PATTERN_ENTRY_USED); | |
| 2203 resource_size = bytes_read_from_cache_; | |
| 2204 } | |
| 2205 | |
| 2206 bool is_small_resource = resource_size < kSmallResourceMaxBytes; | |
| 2207 if (is_small_resource) | |
| 2208 UMA_HISTOGRAM_TIMES("HttpCache.TransactionTime.SmallResource", total_time); | |
| 2209 | |
| 2210 if (!did_send_request) { | |
| 2211 DCHECK(transaction_pattern_ == PATTERN_ENTRY_USED); | |
| 2212 UMA_HISTOGRAM_TIMES("HttpCache.TransactionTime.Used", total_time); | |
| 2213 if (is_small_resource) { | |
| 2214 UMA_HISTOGRAM_TIMES( | |
| 2215 "HttpCache.TransactionTime.Used.SmallResource", total_time); | |
| 2216 } | |
| 2217 return; | |
| 2218 } | |
| 2219 | |
| 2220 TimeDelta before_send_time = send_request_since_ - start_time; | |
| 2221 int before_send_percent = before_send_time * 100 / total_time; | |
| 2222 DCHECK_LE(0, before_send_percent); | |
| 2223 DCHECK_GE(100, before_send_percent); | |
| 2224 | |
| 2225 UMA_HISTOGRAM_TIMES("HttpCache.TransactionTime.SentRequest", total_time); | |
| 2226 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); | |
| 2227 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_percent); | |
| 2228 if (is_small_resource) { | |
| 2229 UMA_HISTOGRAM_TIMES("HttpCache.TransactionTime.SentRequest.SmallResource", | |
| 2230 total_time); | |
| 2231 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.SmallResource", | |
| 2232 before_send_time); | |
| 2233 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.SmallResource", | |
| 2234 before_send_percent); | |
| 2235 } | |
| 2236 | |
| 2237 // TODO(gavinp): Remove or minimize these histograms, particularly the ones | |
| 2238 // below this comment after we have received initial data. | |
| 2239 switch (transaction_pattern_) { | |
| 2240 case PATTERN_ENTRY_NOT_CACHED: { | |
| 2241 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); | |
| 2242 UMA_HISTOGRAM_PERCENTAGE( | |
| 2243 "HttpCache.PercentBeforeSend.NotCached", before_send_percent); | |
| 2244 if (is_small_resource) { | |
| 2245 UMA_HISTOGRAM_TIMES( | |
| 2246 "HttpCache.BeforeSend.NotCached.SmallResource", before_send_time); | |
| 2247 UMA_HISTOGRAM_PERCENTAGE( | |
| 2248 "HttpCache.PercentBeforeSend.NotCached.SmallResource", | |
| 2249 before_send_percent); | |
| 2250 } | |
| 2251 break; | |
| 2252 } | |
| 2253 case PATTERN_ENTRY_VALIDATED: { | |
| 2254 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); | |
| 2255 UMA_HISTOGRAM_PERCENTAGE( | |
| 2256 "HttpCache.PercentBeforeSend.Validated", before_send_percent); | |
| 2257 if (is_small_resource) { | |
| 2258 UMA_HISTOGRAM_TIMES( | |
| 2259 "HttpCache.BeforeSend.Validated.SmallResource", before_send_time); | |
| 2260 UMA_HISTOGRAM_PERCENTAGE( | |
| 2261 "HttpCache.PercentBeforeSend.Validated.SmallResource", | |
| 2262 before_send_percent); | |
| 2263 } | |
| 2264 break; | |
| 2265 } | |
| 2266 case PATTERN_ENTRY_UPDATED: { | |
| 2267 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); | |
| 2268 UMA_HISTOGRAM_PERCENTAGE( | |
| 2269 "HttpCache.PercentBeforeSend.Updated", before_send_percent); | |
| 2270 if (is_small_resource) { | |
| 2271 UMA_HISTOGRAM_TIMES( | |
| 2272 "HttpCache.BeforeSend.Updated.SmallResource", before_send_time); | |
| 2273 UMA_HISTOGRAM_PERCENTAGE( | |
| 2274 "HttpCache.PercentBeforeSend.Updated.SmallResource", | |
| 2275 before_send_percent); | |
| 2276 } | |
| 2277 break; | |
| 2278 } | |
| 2279 default: | |
| 2280 NOTREACHED(); | |
| 2281 } | |
| 2282 } | |
| 2283 | |
| 2115 } // namespace net | 2284 } // namespace net |
| OLD | NEW |