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 23 matching lines...) Expand all Loading... | |
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 net { | 42 namespace net { |
43 | 43 |
44 namespace { | |
rvargas (doing something else)
2012/07/21 02:24:21
Move this outside of net
gavinp
2012/07/25 01:07:01
Done. You didn't say why: is it because it doesn't
rvargas (doing something else)
2012/07/25 19:41:04
In part because it's the common pattern everywhere
| |
45 | |
46 // The cutoff for tagging small transactions in histograms; this size was chosen | |
47 // to cover resources likely to be received in a single TCP window. With an | |
48 // initial CWND of 10, and an MTU of 1500 bytes, with TCP and HTTP framing | |
49 // overhead this is a size relatively likely to take only one RTT. | |
50 const int kSmallResourceMaxBytes = 14 * 1024; | |
51 | |
52 // Requests faster than this do not report as many performance histograms. | |
53 const int kFastRequestCutoffMs = 5; | |
54 | |
55 } | |
56 | |
44 struct HeaderNameAndValue { | 57 struct HeaderNameAndValue { |
45 const char* name; | 58 const char* name; |
46 const char* value; | 59 const char* value; |
47 }; | 60 }; |
48 | 61 |
49 // If the request includes one of these request headers, then avoid caching | 62 // If the request includes one of these request headers, then avoid caching |
50 // to avoid getting confused. | 63 // to avoid getting confused. |
51 static const HeaderNameAndValue kPassThroughHeaders[] = { | 64 static const HeaderNameAndValue kPassThroughHeaders[] = { |
52 { "if-unmodified-since", NULL }, // causes unexpected 412s | 65 { "if-unmodified-since", NULL }, // causes unexpected 412s |
53 { "if-match", NULL }, // causes unexpected 412s | 66 { "if-match", NULL }, // causes unexpected 412s |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 handling_206_(false), | 132 handling_206_(false), |
120 cache_pending_(false), | 133 cache_pending_(false), |
121 done_reading_(false), | 134 done_reading_(false), |
122 read_offset_(0), | 135 read_offset_(0), |
123 effective_load_flags_(0), | 136 effective_load_flags_(0), |
124 write_len_(0), | 137 write_len_(0), |
125 final_upload_progress_(0), | 138 final_upload_progress_(0), |
126 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 139 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
127 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( | 140 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( |
128 base::Bind(&Transaction::OnIOComplete, | 141 base::Bind(&Transaction::OnIOComplete, |
129 weak_factory_.GetWeakPtr()))) { | 142 weak_factory_.GetWeakPtr()))), |
143 disposition_(DISPOSITION_UNDEFINED) { | |
130 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == | 144 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == |
131 arraysize(kValidationHeaders), | 145 arraysize(kValidationHeaders), |
132 Invalid_number_of_validation_headers); | 146 Invalid_number_of_validation_headers); |
133 } | 147 } |
134 | 148 |
135 HttpCache::Transaction::~Transaction() { | 149 HttpCache::Transaction::~Transaction() { |
136 // We may have to issue another IO, but we should never invoke the callback_ | 150 // We may have to issue another IO, but we should never invoke the callback_ |
137 // after this point. | 151 // after this point. |
138 callback_.Reset(); | 152 callback_.Reset(); |
139 | 153 |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
663 result); | 677 result); |
664 cache_pending_ = false; | 678 cache_pending_ = false; |
665 | 679 |
666 if (!ShouldPassThrough()) { | 680 if (!ShouldPassThrough()) { |
667 cache_key_ = cache_->GenerateCacheKey(request_); | 681 cache_key_ = cache_->GenerateCacheKey(request_); |
668 | 682 |
669 // Requested cache access mode. | 683 // Requested cache access mode. |
670 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { | 684 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { |
671 mode_ = READ; | 685 mode_ = READ; |
672 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { | 686 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { |
687 // Don't record a load that isn't really testing the cache. | |
rvargas (doing something else)
2012/07/21 02:24:21
This goes through the cache.
gavinp
2012/07/25 01:07:01
Good point. Comment fixed. Srsly fixed.
| |
688 MaybeUpdateDisposition(DISPOSITION_DO_NOT_RECORD); | |
673 mode_ = WRITE; | 689 mode_ = WRITE; |
674 } else { | 690 } else { |
675 mode_ = READ_WRITE; | 691 mode_ = READ_WRITE; |
676 } | 692 } |
677 | 693 |
678 // Downgrade to UPDATE if the request has been externally conditionalized. | 694 // Downgrade to UPDATE if the request has been externally conditionalized. |
679 if (external_validation_.initialized) { | 695 if (external_validation_.initialized) { |
680 if (mode_ & WRITE) { | 696 if (mode_ & WRITE) { |
681 // Strip off the READ_DATA bit (and maybe add back a READ_META bit | 697 // Strip off the READ_DATA bit (and maybe add back a READ_META bit |
682 // in case READ was off). | 698 // in case READ was off). |
(...skipping 28 matching lines...) Expand all Loading... | |
711 // This is only set if we have something to do with the response. | 727 // This is only set if we have something to do with the response. |
712 range_requested_ = (partial_.get() != NULL); | 728 range_requested_ = (partial_.get() != NULL); |
713 | 729 |
714 return OK; | 730 return OK; |
715 } | 731 } |
716 | 732 |
717 int HttpCache::Transaction::DoSendRequest() { | 733 int HttpCache::Transaction::DoSendRequest() { |
718 DCHECK(mode_ & WRITE || mode_ == NONE); | 734 DCHECK(mode_ & WRITE || mode_ == NONE); |
719 DCHECK(!network_trans_.get()); | 735 DCHECK(!network_trans_.get()); |
720 | 736 |
737 started_reading_since_ = TimeTicks::Now(); | |
rvargas (doing something else)
2012/07/21 02:24:21
The name is weird for what it is measuring.
gavinp
2012/07/25 01:07:01
Yup. Do you like the new name and use?
| |
738 | |
721 // Create a network transaction. | 739 // Create a network transaction. |
722 int rv = cache_->network_layer_->CreateTransaction(&network_trans_); | 740 int rv = cache_->network_layer_->CreateTransaction(&network_trans_); |
723 if (rv != OK) | 741 if (rv != OK) |
724 return rv; | 742 return rv; |
725 | 743 |
726 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 744 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
727 rv = network_trans_->Start(request_, io_callback_, net_log_); | 745 rv = network_trans_->Start(request_, io_callback_, net_log_); |
728 return rv; | 746 return rv; |
729 } | 747 } |
730 | 748 |
731 int HttpCache::Transaction::DoSendRequestComplete(int result) { | 749 int HttpCache::Transaction::DoSendRequestComplete(int result) { |
732 if (!cache_) | 750 if (!cache_) |
733 return ERR_UNEXPECTED; | 751 return ERR_UNEXPECTED; |
734 | 752 |
735 if (result == OK) { | 753 if (result == OK) { |
736 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 754 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
737 return OK; | 755 return OK; |
738 } | 756 } |
739 | 757 |
758 // Do not record requests that have network errors or restarts. | |
759 MaybeUpdateDisposition(DISPOSITION_DO_NOT_RECORD); | |
740 if (IsCertificateError(result)) { | 760 if (IsCertificateError(result)) { |
741 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 761 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
742 // If we get a certificate error, then there is a certificate in ssl_info, | 762 // If we get a certificate error, then there is a certificate in ssl_info, |
743 // so GetResponseInfo() should never return NULL here. | 763 // so GetResponseInfo() should never return NULL here. |
744 DCHECK(response); | 764 DCHECK(response); |
745 response_.ssl_info = response->ssl_info; | 765 response_.ssl_info = response->ssl_info; |
746 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 766 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
747 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 767 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
748 DCHECK(response); | 768 DCHECK(response); |
749 response_.cert_request_info = response->cert_request_info; | 769 response_.cert_request_info = response->cert_request_info; |
(...skipping 10 matching lines...) Expand all Loading... | |
760 auth_response_ = *new_response; | 780 auth_response_ = *new_response; |
761 return OK; | 781 return OK; |
762 } | 782 } |
763 | 783 |
764 new_response_ = new_response; | 784 new_response_ = new_response; |
765 if (!ValidatePartialResponse() && !auth_response_.headers) { | 785 if (!ValidatePartialResponse() && !auth_response_.headers) { |
766 // Something went wrong with this request and we have to restart it. | 786 // 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 | 787 // If we have an authentication response, we are exposed to weird things |
768 // hapenning if the user cancels the authentication before we receive | 788 // hapenning if the user cancels the authentication before we receive |
769 // the new response. | 789 // the new response. |
790 MaybeUpdateDisposition(DISPOSITION_DO_NOT_RECORD); | |
770 response_ = HttpResponseInfo(); | 791 response_ = HttpResponseInfo(); |
771 network_trans_.reset(); | 792 network_trans_.reset(); |
772 new_response_ = NULL; | 793 new_response_ = NULL; |
773 next_state_ = STATE_SEND_REQUEST; | 794 next_state_ = STATE_SEND_REQUEST; |
774 return OK; | 795 return OK; |
775 } | 796 } |
776 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { | 797 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { |
777 // We have stored the full entry, but it changed and the server is | 798 // We have stored the full entry, but it changed and the server is |
778 // sending a range. We have to delete the old entry. | 799 // sending a range. We have to delete the old entry. |
779 DoneWritingToEntry(false); | 800 DoneWritingToEntry(false); |
780 } | 801 } |
781 | 802 |
rvargas (doing something else)
2012/07/25 19:41:04
Do you mind keeping this line?
gavinp
2012/07/28 01:36:06
Done.
| |
782 if (new_response_->headers->response_code() == 416) { | 803 if (new_response_->headers->response_code() == 416) { |
783 DCHECK_EQ(NONE, mode_); | 804 DCHECK_EQ(NONE, mode_); |
784 response_ = *new_response_; | 805 response_ = *new_response_; |
785 return OK; | 806 return OK; |
786 } | 807 } |
787 | 808 |
788 if (mode_ == WRITE && | 809 if (mode_ == WRITE && |
789 (request_->method == "PUT" || request_->method == "DELETE")) { | 810 (request_->method == "PUT" || request_->method == "DELETE")) { |
790 if (new_response->headers->response_code() == 200) { | 811 if (new_response->headers->response_code() == 200) { |
791 int ret = cache_->DoomEntry(cache_key_, NULL); | 812 int ret = cache_->DoomEntry(cache_key_, NULL); |
792 DCHECK_EQ(OK, ret); | 813 DCHECK_EQ(OK, ret); |
793 } | 814 } |
794 mode_ = NONE; | 815 mode_ = NONE; |
795 } | 816 } |
796 | 817 |
797 // Are we expecting a response to a conditional query? | 818 // Are we expecting a response to a conditional query? |
798 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 819 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
799 if (new_response->headers->response_code() == 304 || handling_206_) { | 820 if (new_response->headers->response_code() == 304 || handling_206_) { |
821 MaybeUpdateDisposition(DISPOSITION_ENTRY_VALIDATED_304); | |
rvargas (doing something else)
2012/07/21 02:24:21
This is more than just 304. Why not drop the 304 p
gavinp
2012/07/25 01:07:01
Done, the new more consistant names are good. Than
rvargas (doing something else)
2012/07/25 19:41:04
No other case, but to know that 206 doesn't matter
| |
800 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 822 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
801 return OK; | 823 return OK; |
802 } | 824 } |
825 MaybeUpdateDisposition(DISPOSITION_ENTRY_VALIDATED_200); | |
rvargas (doing something else)
2012/07/21 02:24:21
What about names that match the histogram? used, v
gavinp
2012/07/25 01:07:01
Done.
| |
803 mode_ = WRITE; | 826 mode_ = WRITE; |
804 } | 827 } |
805 | 828 |
806 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; | 829 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; |
807 return OK; | 830 return OK; |
808 } | 831 } |
809 | 832 |
810 int HttpCache::Transaction::DoNetworkRead() { | 833 int HttpCache::Transaction::DoNetworkRead() { |
811 next_state_ = STATE_NETWORK_READ_COMPLETE; | 834 next_state_ = STATE_NETWORK_READ_COMPLETE; |
812 return network_trans_->Read(read_buf_, io_buf_len_, io_callback_); | 835 return network_trans_->Read(read_buf_, io_buf_len_, io_callback_); |
(...skipping 27 matching lines...) Expand all Loading... | |
840 | 863 |
841 next_state_ = STATE_OPEN_ENTRY; | 864 next_state_ = STATE_OPEN_ENTRY; |
842 return OK; | 865 return OK; |
843 } | 866 } |
844 | 867 |
845 int HttpCache::Transaction::DoOpenEntry() { | 868 int HttpCache::Transaction::DoOpenEntry() { |
846 DCHECK(!new_entry_); | 869 DCHECK(!new_entry_); |
847 next_state_ = STATE_OPEN_ENTRY_COMPLETE; | 870 next_state_ = STATE_OPEN_ENTRY_COMPLETE; |
848 cache_pending_ = true; | 871 cache_pending_ = true; |
849 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); | 872 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); |
873 open_entry_since_ = TimeTicks::Now(); | |
850 return cache_->OpenEntry(cache_key_, &new_entry_, this); | 874 return cache_->OpenEntry(cache_key_, &new_entry_, this); |
851 } | 875 } |
852 | 876 |
853 int HttpCache::Transaction::DoOpenEntryComplete(int result) { | 877 int HttpCache::Transaction::DoOpenEntryComplete(int result) { |
854 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is | 878 // 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 | 879 // OK, otherwise the cache will end up with an active entry without any |
856 // transaction attached. | 880 // transaction attached. |
857 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); | 881 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); |
858 cache_pending_ = false; | 882 cache_pending_ = false; |
859 if (result == OK) { | 883 if (result == OK) { |
860 next_state_ = STATE_ADD_TO_ENTRY; | 884 next_state_ = STATE_ADD_TO_ENTRY; |
861 return OK; | 885 return OK; |
862 } | 886 } |
863 | 887 |
864 if (result == ERR_CACHE_RACE) { | 888 if (result == ERR_CACHE_RACE) { |
865 next_state_ = STATE_INIT_ENTRY; | 889 next_state_ = STATE_INIT_ENTRY; |
866 return OK; | 890 return OK; |
867 } | 891 } |
868 | 892 |
893 MaybeUpdateDisposition(DISPOSITION_NO_ENTRY); | |
869 if (request_->method == "PUT" || request_->method == "DELETE") { | 894 if (request_->method == "PUT" || request_->method == "DELETE") { |
870 DCHECK(mode_ == READ_WRITE || mode_ == WRITE); | 895 DCHECK(mode_ == READ_WRITE || mode_ == WRITE); |
871 mode_ = NONE; | 896 mode_ = NONE; |
872 next_state_ = STATE_SEND_REQUEST; | 897 next_state_ = STATE_SEND_REQUEST; |
873 return OK; | 898 return OK; |
874 } | 899 } |
875 | 900 |
876 if (mode_ == READ_WRITE) { | 901 if (mode_ == READ_WRITE) { |
877 mode_ = WRITE; | 902 mode_ = WRITE; |
878 next_state_ = STATE_CREATE_ENTRY; | 903 next_state_ = STATE_CREATE_ENTRY; |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1232 // o if we can read or write, then we should check if the cache entry needs | 1257 // 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 | 1258 // 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. | 1259 // from the cache if the cache entry is already valid. |
1235 // | 1260 // |
1236 // o if we are set to UPDATE, then we are handling an externally | 1261 // o if we are set to UPDATE, then we are handling an externally |
1237 // conditionalized request (if-modified-since / if-none-match). We check | 1262 // conditionalized request (if-modified-since / if-none-match). We check |
1238 // if the request headers define a validation request. | 1263 // if the request headers define a validation request. |
1239 // | 1264 // |
1240 switch (mode_) { | 1265 switch (mode_) { |
1241 case READ: | 1266 case READ: |
1267 MaybeUpdateDisposition(DISPOSITION_ENTRY_UNCONDITIONALLY_USED); | |
1268 started_reading_since_ = TimeTicks::Now(); | |
rvargas (doing something else)
2012/07/21 02:24:21
Now I'm confused about what do you want to measure
gavinp
2012/07/25 01:07:01
You're right, it was too confusing. I came into th
| |
1242 result = BeginCacheRead(); | 1269 result = BeginCacheRead(); |
1243 break; | 1270 break; |
1244 case READ_WRITE: | 1271 case READ_WRITE: |
1245 result = BeginPartialCacheValidation(); | 1272 result = BeginPartialCacheValidation(); |
1246 break; | 1273 break; |
1247 case UPDATE: | 1274 case UPDATE: |
1248 result = BeginExternallyConditionalizedRequest(); | 1275 result = BeginExternallyConditionalizedRequest(); |
1249 break; | 1276 break; |
1250 case WRITE: | 1277 case WRITE: |
1251 default: | 1278 default: |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1296 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); | 1323 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
1297 return entry_->disk_entry->ReadData(kMetadataIndex, 0, response_.metadata, | 1324 return entry_->disk_entry->ReadData(kMetadataIndex, 0, response_.metadata, |
1298 response_.metadata->size(), | 1325 response_.metadata->size(), |
1299 io_callback_); | 1326 io_callback_); |
1300 } | 1327 } |
1301 | 1328 |
1302 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { | 1329 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { |
1303 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1330 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
1304 if (result != response_.metadata->size()) | 1331 if (result != response_.metadata->size()) |
1305 return OnCacheReadError(result, false); | 1332 return OnCacheReadError(result, false); |
1306 | 1333 |
rvargas (doing something else)
2012/07/25 19:41:04
do you mind keeping the line?
| |
1307 return OK; | 1334 return OK; |
1308 } | 1335 } |
1309 | 1336 |
1310 int HttpCache::Transaction::DoCacheQueryData() { | 1337 int HttpCache::Transaction::DoCacheQueryData() { |
1311 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; | 1338 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; |
1312 | 1339 |
1313 // Balanced in DoCacheQueryDataComplete. | 1340 // Balanced in DoCacheQueryDataComplete. |
1314 return entry_->disk_entry->ReadyForSparseIO(io_callback_); | 1341 return entry_->disk_entry->ReadyForSparseIO(io_callback_); |
1315 } | 1342 } |
1316 | 1343 |
(...skipping 22 matching lines...) Expand all Loading... | |
1339 | 1366 |
1340 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { | 1367 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { |
1341 if (net_log_.IsLoggingAllEvents()) { | 1368 if (net_log_.IsLoggingAllEvents()) { |
1342 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, | 1369 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, |
1343 result); | 1370 result); |
1344 } | 1371 } |
1345 | 1372 |
1346 if (!cache_) | 1373 if (!cache_) |
1347 return ERR_UNEXPECTED; | 1374 return ERR_UNEXPECTED; |
1348 | 1375 |
1349 if (partial_.get()) | 1376 if (partial_.get()) { |
1377 // Partial requests are confusing to report in histograms because they may | |
1378 // have multiple underlying requests. | |
1379 MaybeUpdateDisposition(DISPOSITION_DO_NOT_RECORD); | |
1350 return DoPartialCacheReadCompleted(result); | 1380 return DoPartialCacheReadCompleted(result); |
1381 } | |
1351 | 1382 |
1352 if (result > 0) { | 1383 if (result > 0) { |
1353 read_offset_ += result; | 1384 read_offset_ += result; |
1354 } else if (result == 0) { // End of file. | 1385 } else if (result == 0) { // End of file. |
1386 RecordHistograms(read_offset_); | |
1355 cache_->DoneReadingFromEntry(entry_, this); | 1387 cache_->DoneReadingFromEntry(entry_, this); |
1356 entry_ = NULL; | 1388 entry_ = NULL; |
1357 } else { | 1389 } else { |
1358 return OnCacheReadError(result, false); | 1390 return OnCacheReadError(result, false); |
1359 } | 1391 } |
1360 return result; | 1392 return result; |
1361 } | 1393 } |
1362 | 1394 |
1363 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { | 1395 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { |
1364 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; | 1396 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1492 | 1524 |
1493 // If there is more than one validation header, we can't treat this request as | 1525 // 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 | 1526 // 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). | 1527 // will give us a response for (and they could be contradictory). |
1496 if (external_validation_error) { | 1528 if (external_validation_error) { |
1497 LOG(WARNING) << "Multiple or malformed validation headers found."; | 1529 LOG(WARNING) << "Multiple or malformed validation headers found."; |
1498 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 1530 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
1499 } | 1531 } |
1500 | 1532 |
1501 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { | 1533 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { |
1534 MaybeUpdateDisposition(DISPOSITION_DO_NOT_RECORD); | |
1502 partial_.reset(new PartialData); | 1535 partial_.reset(new PartialData); |
1503 if (request_->method == "GET" && partial_->Init(request_->extra_headers)) { | 1536 if (request_->method == "GET" && partial_->Init(request_->extra_headers)) { |
1504 // We will be modifying the actual range requested to the server, so | 1537 // We will be modifying the actual range requested to the server, so |
1505 // let's remove the header here. | 1538 // let's remove the header here. |
1506 custom_request_.reset(new HttpRequestInfo(*request_)); | 1539 custom_request_.reset(new HttpRequestInfo(*request_)); |
1507 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); | 1540 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); |
1508 request_ = custom_request_.get(); | 1541 request_ = custom_request_.get(); |
1509 partial_->SetHeaders(custom_request_->extra_headers); | 1542 partial_->SetHeaders(custom_request_->extra_headers); |
1510 } else { | 1543 } else { |
1511 // The range is invalid or we cannot handle it properly. | 1544 // The range is invalid or we cannot handle it properly. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1563 | 1596 |
1564 return OK; | 1597 return OK; |
1565 } | 1598 } |
1566 | 1599 |
1567 int HttpCache::Transaction::BeginCacheValidation() { | 1600 int HttpCache::Transaction::BeginCacheValidation() { |
1568 DCHECK(mode_ == READ_WRITE); | 1601 DCHECK(mode_ == READ_WRITE); |
1569 | 1602 |
1570 bool skip_validation = effective_load_flags_ & LOAD_PREFERRING_CACHE || | 1603 bool skip_validation = effective_load_flags_ & LOAD_PREFERRING_CACHE || |
1571 !RequiresValidation(); | 1604 !RequiresValidation(); |
1572 | 1605 |
1573 if (truncated_) | 1606 if (truncated_) { |
1607 // Truncated entries can cause partial gets, so we shouldn't record this | |
1608 // load in histograms. | |
1609 MaybeUpdateDisposition(DISPOSITION_DO_NOT_RECORD); | |
1574 skip_validation = !partial_->initial_validation(); | 1610 skip_validation = !partial_->initial_validation(); |
1611 } | |
1575 | 1612 |
1576 if ((partial_.get() && !partial_->IsCurrentRangeCached()) || invalid_range_) | 1613 if ((partial_.get() && !partial_->IsCurrentRangeCached()) || invalid_range_) |
1577 skip_validation = false; | 1614 skip_validation = false; |
1578 | 1615 |
1579 if (skip_validation) { | 1616 if (skip_validation) { |
1617 MaybeUpdateDisposition(DISPOSITION_ENTRY_UNCONDITIONALLY_USED); | |
1618 started_reading_since_ = TimeTicks::Now(); | |
1580 if (partial_.get()) { | 1619 if (partial_.get()) { |
1581 // We are going to return the saved response headers to the caller, so | 1620 // We are going to return the saved response headers to the caller, so |
1582 // we may need to adjust them first. | 1621 // we may need to adjust them first. |
1583 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1622 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
1584 return OK; | 1623 return OK; |
1585 } | 1624 } |
1586 cache_->ConvertWriterToReader(entry_); | 1625 cache_->ConvertWriterToReader(entry_); |
1587 mode_ = READ; | 1626 mode_ = READ; |
1588 | 1627 |
1589 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1628 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
1590 next_state_ = STATE_CACHE_READ_METADATA; | 1629 next_state_ = STATE_CACHE_READ_METADATA; |
1591 } else { | 1630 } else { |
1592 // Make the network request conditional, to see if we may reuse our cached | 1631 // 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. | 1632 // 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 | 1633 // 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. | 1634 // either READ or WRITE mode once we hear back from the server. |
1596 if (!ConditionalizeRequest()) { | 1635 if (!ConditionalizeRequest()) { |
1636 MaybeUpdateDisposition(DISPOSITION_ENTRY_UNCONDITIONALLY_USED); | |
1597 DCHECK(!partial_.get()); | 1637 DCHECK(!partial_.get()); |
1598 DCHECK_NE(206, response_.headers->response_code()); | 1638 DCHECK_NE(206, response_.headers->response_code()); |
1599 mode_ = WRITE; | 1639 mode_ = WRITE; |
1600 } | 1640 } |
1601 next_state_ = STATE_SEND_REQUEST; | 1641 next_state_ = STATE_SEND_REQUEST; |
1602 } | 1642 } |
1603 return OK; | 1643 return OK; |
1604 } | 1644 } |
1605 | 1645 |
1606 int HttpCache::Transaction::BeginPartialCacheValidation() { | 1646 int HttpCache::Transaction::BeginPartialCacheValidation() { |
1607 DCHECK(mode_ == READ_WRITE); | 1647 DCHECK(mode_ == READ_WRITE); |
1608 | 1648 |
1609 if (response_.headers->response_code() != 206 && !partial_.get() && | 1649 if (response_.headers->response_code() != 206 && !partial_.get() && |
1610 !truncated_) | 1650 !truncated_) |
1611 return BeginCacheValidation(); | 1651 return BeginCacheValidation(); |
1612 | 1652 |
1653 // Partial requests should not be recorded in histograms. | |
1654 MaybeUpdateDisposition(DISPOSITION_DO_NOT_RECORD); | |
1613 if (range_requested_) { | 1655 if (range_requested_) { |
1614 next_state_ = STATE_CACHE_QUERY_DATA; | 1656 next_state_ = STATE_CACHE_QUERY_DATA; |
1615 return OK; | 1657 return OK; |
1616 } | 1658 } |
1617 // The request is not for a range, but we have stored just ranges. | 1659 // The request is not for a range, but we have stored just ranges. |
1618 partial_.reset(new PartialData()); | 1660 partial_.reset(new PartialData()); |
1619 partial_->SetHeaders(request_->extra_headers); | 1661 partial_->SetHeaders(request_->extra_headers); |
1620 if (!custom_request_.get()) { | 1662 if (!custom_request_.get()) { |
1621 custom_request_.reset(new HttpRequestInfo(*request_)); | 1663 custom_request_.reset(new HttpRequestInfo(*request_)); |
1622 request_ = custom_request_.get(); | 1664 request_ = custom_request_.get(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1663 std::string validator; | 1705 std::string validator; |
1664 response_.headers->EnumerateHeader( | 1706 response_.headers->EnumerateHeader( |
1665 NULL, | 1707 NULL, |
1666 kValidationHeaders[i].related_response_header_name, | 1708 kValidationHeaders[i].related_response_header_name, |
1667 &validator); | 1709 &validator); |
1668 | 1710 |
1669 if (response_.headers->response_code() != 200 || truncated_ || | 1711 if (response_.headers->response_code() != 200 || truncated_ || |
1670 validator.empty() || validator != external_validation_.values[i]) { | 1712 validator.empty() || validator != external_validation_.values[i]) { |
1671 // The externally conditionalized request is not a validation request | 1713 // The externally conditionalized request is not a validation request |
1672 // for our existing cache entry. Proceed with caching disabled. | 1714 // for our existing cache entry. Proceed with caching disabled. |
1715 MaybeUpdateDisposition(DISPOSITION_DO_NOT_RECORD); | |
1673 DoneWritingToEntry(true); | 1716 DoneWritingToEntry(true); |
1674 } | 1717 } |
1675 } | 1718 } |
1676 | 1719 |
1677 next_state_ = STATE_SEND_REQUEST; | 1720 next_state_ = STATE_SEND_REQUEST; |
1678 return OK; | 1721 return OK; |
1679 } | 1722 } |
1680 | 1723 |
1681 int HttpCache::Transaction::RestartNetworkRequest() { | 1724 int HttpCache::Transaction::RestartNetworkRequest() { |
1682 DCHECK(mode_ & WRITE || mode_ == NONE); | 1725 DCHECK(mode_ & WRITE || mode_ == NONE); |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1886 } | 1929 } |
1887 | 1930 |
1888 // 304 is not expected here, but we'll spare the entry (unless it was | 1931 // 304 is not expected here, but we'll spare the entry (unless it was |
1889 // truncated). | 1932 // truncated). |
1890 if (truncated_) | 1933 if (truncated_) |
1891 failure = true; | 1934 failure = true; |
1892 } | 1935 } |
1893 | 1936 |
1894 if (failure) { | 1937 if (failure) { |
1895 // We cannot truncate this entry, it has to be deleted. | 1938 // We cannot truncate this entry, it has to be deleted. |
1939 MaybeUpdateDisposition(DISPOSITION_DO_NOT_RECORD); | |
1896 DoomPartialEntry(false); | 1940 DoomPartialEntry(false); |
1897 mode_ = NONE; | 1941 mode_ = NONE; |
1898 if (!reading_ && !partial_->IsLastRange()) { | 1942 if (!reading_ && !partial_->IsLastRange()) { |
1899 // We'll attempt to issue another network request, this time without us | 1943 // We'll attempt to issue another network request, this time without us |
1900 // messing up the headers. | 1944 // messing up the headers. |
1901 partial_->RestoreHeaders(&custom_request_->extra_headers); | 1945 partial_->RestoreHeaders(&custom_request_->extra_headers); |
1902 partial_.reset(); | 1946 partial_.reset(); |
1903 truncated_ = false; | 1947 truncated_ = false; |
1904 return false; | 1948 return false; |
1905 } | 1949 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2008 | 2052 |
2009 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2053 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
2010 return WriteToEntry(kResponseContentIndex, current_size, data, data_len, | 2054 return WriteToEntry(kResponseContentIndex, current_size, data, data_len, |
2011 callback); | 2055 callback); |
2012 } | 2056 } |
2013 | 2057 |
2014 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2058 void HttpCache::Transaction::DoneWritingToEntry(bool success) { |
2015 if (!entry_) | 2059 if (!entry_) |
2016 return; | 2060 return; |
2017 | 2061 |
2018 if (cache_->mode() == RECORD) | 2062 RecordHistograms(entry_->disk_entry->GetDataSize(kResponseContentIndex)); |
2063 if (cache_->mode() == RECORD) { | |
2019 DVLOG(1) << "Recorded: " << request_->method << request_->url | 2064 DVLOG(1) << "Recorded: " << request_->method << request_->url |
rvargas (doing something else)
2012/07/21 02:24:21
unrelated: we should just delete this log.
gavinp
2012/07/25 01:07:01
Done.
| |
2020 << " status: " << response_.headers->response_code(); | 2065 << " status: " << response_.headers->response_code(); |
2066 } | |
2021 | 2067 |
2022 cache_->DoneWritingToEntry(entry_, success); | 2068 cache_->DoneWritingToEntry(entry_, success); |
2023 entry_ = NULL; | 2069 entry_ = NULL; |
2024 mode_ = NONE; // switch to 'pass through' mode | 2070 mode_ = NONE; // switch to 'pass through' mode |
2025 } | 2071 } |
2026 | 2072 |
2027 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2073 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
2028 DLOG(ERROR) << "ReadData failed: " << result; | 2074 DLOG(ERROR) << "ReadData failed: " << result; |
2029 | 2075 |
2030 // Avoid using this entry in the future. | 2076 // Avoid using this entry in the future. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2105 !response_.headers->HasStrongValidators()) | 2151 !response_.headers->HasStrongValidators()) |
2106 return false; | 2152 return false; |
2107 | 2153 |
2108 return true; | 2154 return true; |
2109 } | 2155 } |
2110 | 2156 |
2111 void HttpCache::Transaction::OnIOComplete(int result) { | 2157 void HttpCache::Transaction::OnIOComplete(int result) { |
2112 DoLoop(result); | 2158 DoLoop(result); |
2113 } | 2159 } |
2114 | 2160 |
2161 void HttpCache::Transaction::MaybeUpdateDisposition( | |
rvargas (doing something else)
2012/07/21 02:24:21
Remove the "maybe" part from the name.
gavinp
2012/07/25 01:07:01
Done.
| |
2162 const Disposition disposition) { | |
rvargas (doing something else)
2012/07/21 02:24:21
Drop the const
gavinp
2012/07/25 01:07:01
Done.
| |
2163 // Once a transaction has been found to have a complicated disposition, it | |
2164 // can't change to any other simpler disposition. | |
2165 if (disposition_ == DISPOSITION_DO_NOT_RECORD) | |
rvargas (doing something else)
2012/07/21 02:24:21
is this really worth the extra work?. We could jus
gavinp
2012/07/25 01:07:01
Done. Having both and the DCHECK was very good for
gavinp
2012/07/25 14:00:27
I should have updated this comment before uploadin
| |
2166 return; | |
2167 DCHECK(disposition_ == DISPOSITION_UNDEFINED || | |
2168 disposition == DISPOSITION_DO_NOT_RECORD); | |
rvargas (doing something else)
2012/07/21 02:24:21
cannot reach do_not_record
gavinp
2012/07/25 01:07:01
Hrm, you are wrong. Does this mean I'm naming my p
rvargas (doing something else)
2012/07/25 19:41:04
Why am I wrong? the previous line returns if p_not
gavinp
2012/07/28 01:36:06
The previous line compares the member variable |di
| |
2169 disposition_ = disposition; | |
2170 } | |
2171 | |
2172 void HttpCache::Transaction::RecordHistograms(const int resource_size) { | |
rvargas (doing something else)
2012/07/21 02:24:21
Drop the const
gavinp
2012/07/25 01:07:01
Done.
| |
2173 if (cache_->mode() != NORMAL || request_->method != "GET") | |
2174 return; | |
2175 | |
2176 UMA_HISTOGRAM_BOOLEAN( | |
2177 "HttpCache.DoNotRecord", disposition_ == DISPOSITION_DO_NOT_RECORD); | |
2178 if (disposition_ == DISPOSITION_DO_NOT_RECORD) | |
2179 return; | |
2180 DCHECK(!range_requested_); | |
2181 DCHECK_NE(DISPOSITION_UNDEFINED, disposition_); | |
gavinp
2012/07/20 17:19:24
Should these DCHECKs be changed into early returns
rvargas (doing something else)
2012/07/21 02:24:21
DCHECKS seem file to me.
gavinp
2012/07/25 01:07:01
What I found very interesting was how many differe
| |
2182 DCHECK(!open_entry_since_.is_null()); | |
2183 DCHECK(!started_reading_since_.is_null()); | |
2184 | |
2185 const TimeDelta before_reading_time = | |
rvargas (doing something else)
2012/07/21 02:24:21
I also think we should drop the const on these var
gavinp
2012/07/25 01:07:01
Done.
| |
2186 started_reading_since_ - open_entry_since_; | |
2187 const TimeDelta reading_time = TimeTicks::Now() - started_reading_since_; | |
2188 const TimeDelta total_time = before_reading_time + reading_time; | |
2189 | |
2190 UMA_HISTOGRAM_TIMES("HttpCache.TimeBlocked", before_reading_time); | |
rvargas (doing something else)
2012/07/21 02:24:21
This puts together all cache types under the same
| |
2191 UMA_HISTOGRAM_TIMES("HttpCache.TimeReading", reading_time); | |
2192 | |
2193 const bool is_small_resource = resource_size < kSmallResourceMaxBytes; | |
rvargas (doing something else)
2012/07/21 02:24:21
This is not what the caller is passing... I mean,
gavinp
2012/07/25 01:07:01
Good point. It's also undefined since I don't real
| |
2194 if (is_small_resource) { | |
2195 UMA_HISTOGRAM_TIMES( | |
2196 "HttpCache.TimeBlocked.SmallResource", before_reading_time); | |
rvargas (doing something else)
2012/07/21 02:24:21
nit: TimeBlocked?
| |
2197 UMA_HISTOGRAM_TIMES("HttpCache.TimeReading.SmallResource", reading_time); | |
2198 } | |
2199 | |
2200 // The more detailed histograms are only interesting for requests that are not | |
rvargas (doing something else)
2012/07/21 02:24:21
why?
gavinp
2012/07/25 01:07:01
Good point I had no reason whatsoever to actually
| |
2201 // fast. | |
2202 if (total_time.InMilliseconds() < kFastRequestCutoffMs) | |
2203 return; | |
2204 | |
2205 const int before_reading_percent = before_reading_time * 100 / total_time; | |
2206 DCHECK_LE(0, before_reading_percent); | |
2207 DCHECK_GE(100, before_reading_percent); | |
2208 | |
2209 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBlocked", before_reading_percent); | |
rvargas (doing something else)
2012/07/21 02:24:21
nit: Not really blocked
gavinp
2012/07/25 01:07:01
Now named how long before send. The request isn't
| |
2210 if (is_small_resource) | |
2211 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBlocked.SmallResource", | |
2212 before_reading_percent); | |
2213 | |
2214 // TODO(gavinp): Remove or minimize these histograms, particularly the ones | |
2215 // below this comment after we have received initial data. | |
2216 switch (disposition_) { | |
rvargas (doing something else)
2012/07/21 02:24:21
nit: I'm not really happy with the term "dispositi
gavinp
2012/07/25 01:07:01
Now that you point it out, I hate the name too.
T
| |
2217 case DISPOSITION_NO_ENTRY: { | |
2218 UMA_HISTOGRAM_TIMES( | |
2219 "HttpCache.TimeBlocked.NotCached", before_reading_time); | |
2220 UMA_HISTOGRAM_PERCENTAGE( | |
2221 "HttpCache.PercentBlocked.NotCached", before_reading_percent); | |
rvargas (doing something else)
2012/07/21 02:24:21
Id suggest just dropping the absolute times.
gavinp
2012/07/25 01:07:01
You might be right. I'd like to wait for results.
| |
2222 if (is_small_resource) { | |
2223 UMA_HISTOGRAM_PERCENTAGE( | |
2224 "HttpCache.PercentBlocked.NotCached.SmallResource", | |
2225 before_reading_percent); | |
2226 } | |
2227 break; | |
2228 } | |
2229 case DISPOSITION_ENTRY_UNCONDITIONALLY_USED: { | |
2230 UMA_HISTOGRAM_TIMES( | |
2231 "HttpCache.TimeBlocked.Used", before_reading_time); | |
2232 UMA_HISTOGRAM_PERCENTAGE( | |
2233 "HttpCache.PercentBlocked.Used", before_reading_percent); | |
2234 if (is_small_resource) { | |
2235 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBlocked.Used.SmallResource", | |
2236 before_reading_percent); | |
2237 } | |
2238 break; | |
2239 } | |
2240 case DISPOSITION_ENTRY_VALIDATED_304: { | |
2241 UMA_HISTOGRAM_TIMES( | |
2242 "HttpCache.TimeBlocked.Validated", before_reading_time); | |
2243 UMA_HISTOGRAM_PERCENTAGE( | |
2244 "HttpCache.PercentBlocked.Validated", before_reading_percent); | |
2245 if (is_small_resource) { | |
2246 UMA_HISTOGRAM_PERCENTAGE( | |
2247 "HttpCache.PercentBlocked.Validated.SmallResource", | |
2248 before_reading_percent); | |
2249 } | |
2250 break; | |
2251 } | |
2252 case DISPOSITION_ENTRY_VALIDATED_200: { | |
2253 UMA_HISTOGRAM_TIMES( | |
2254 "HttpCache.TimeBlocked.Updated", before_reading_time); | |
2255 UMA_HISTOGRAM_PERCENTAGE( | |
2256 "HttpCache.PercentBlocked.Updated", before_reading_percent); | |
2257 if (is_small_resource) { | |
2258 UMA_HISTOGRAM_PERCENTAGE( | |
2259 "HttpCache.PercentBlocked.Updated.SmallResource", | |
2260 before_reading_percent); | |
2261 } | |
2262 break; | |
2263 } | |
2264 case DISPOSITION_UNDEFINED: | |
2265 default: | |
2266 NOTREACHED(); | |
2267 } | |
2268 } | |
2269 | |
2115 } // namespace net | 2270 } // namespace net |
OLD | NEW |