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/infinite_cache.h" | 5 #include "net/http/infinite_cache.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 | 38 |
| 39 // Flags to use with a particular resource. | 39 // Flags to use with a particular resource. |
| 40 enum Flags { | 40 enum Flags { |
| 41 NO_CACHE = 1 << 0, | 41 NO_CACHE = 1 << 0, |
| 42 NO_STORE = 1 << 1, | 42 NO_STORE = 1 << 1, |
| 43 EXPIRED = 1 << 2, | 43 EXPIRED = 1 << 2, |
| 44 TRUNCATED = 1 << 3, | 44 TRUNCATED = 1 << 3, |
| 45 RESUMABLE = 1 << 4, | 45 RESUMABLE = 1 << 4, |
| 46 REVALIDATEABLE = 1 << 5, | 46 REVALIDATEABLE = 1 << 5, |
| 47 DOOM_METHOD = 1 << 6, | 47 DOOM_METHOD = 1 << 6, |
| 48 CACHED = 1 << 7 | 48 CACHED = 1 << 7, |
| 49 GA_JS_HTTP = 1 << 8, | |
| 50 GA_JS_HTTPS = 1 << 9, // 0 means HTTP, 1 means HTTPS | |
|
rvargas (doing something else)
2012/09/29 02:12:51
stale comment.
willchan no longer on Chromium
2012/09/29 02:18:27
Done.
| |
| 49 }; | 51 }; |
| 50 | 52 |
| 51 const int kKeySizeBytes = 20; | 53 const int kKeySizeBytes = 20; |
| 52 COMPILE_ASSERT(base::kSHA1Length == static_cast<unsigned>(kKeySizeBytes), | 54 COMPILE_ASSERT(base::kSHA1Length == static_cast<unsigned>(kKeySizeBytes), |
| 53 invalid_key_length); | 55 invalid_key_length); |
| 54 struct Key { | 56 struct Key { |
| 55 char value[kKeySizeBytes]; | 57 char value[kKeySizeBytes]; |
| 56 }; | 58 }; |
| 57 | 59 |
| 58 // The actual data that we store for every resource. | 60 // The actual data that we store for every resource. |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 size_t operator()(const Key& key) const { | 221 size_t operator()(const Key& key) const { |
| 220 return base::Hash(key.value, kKeySizeBytes); | 222 return base::Hash(key.value, kKeySizeBytes); |
| 221 } | 223 } |
| 222 }; | 224 }; |
| 223 #endif | 225 #endif |
| 224 | 226 |
| 225 } // BASE_HASH_NAMESPACE | 227 } // BASE_HASH_NAMESPACE |
| 226 | 228 |
| 227 namespace net { | 229 namespace net { |
| 228 | 230 |
| 231 static const char kGaJsHttpUrl[] = "http://www.google-analytics.com/ga.js"; | |
|
rvargas (doing something else)
2012/09/29 02:12:51
this should go into the anonymous namespace
willchan no longer on Chromium
2012/09/29 02:18:27
Done.
| |
| 232 static const char kGaJsHttpsUrl[] = "https://ssl.google-analytics.com/ga.js"; | |
| 233 | |
| 229 struct InfiniteCacheTransaction::ResourceData { | 234 struct InfiniteCacheTransaction::ResourceData { |
| 230 ResourceData() { | 235 ResourceData() { |
| 231 memset(this, 0, sizeof(*this)); | 236 memset(this, 0, sizeof(*this)); |
| 232 } | 237 } |
| 233 | 238 |
| 234 Key key; | 239 Key key; |
| 235 Details details; | 240 Details details; |
| 236 }; | 241 }; |
| 237 | 242 |
| 238 InfiniteCacheTransaction::InfiniteCacheTransaction(InfiniteCache* cache) | 243 InfiniteCacheTransaction::InfiniteCacheTransaction(InfiniteCache* cache) |
| 239 : cache_(cache->AsWeakPtr()), must_doom_entry_(false) { | 244 : cache_(cache->AsWeakPtr()) { |
| 240 } | 245 } |
| 241 | 246 |
| 242 InfiniteCacheTransaction::~InfiniteCacheTransaction() { | 247 InfiniteCacheTransaction::~InfiniteCacheTransaction() { |
| 243 Finish(); | 248 Finish(); |
| 244 } | 249 } |
| 245 | 250 |
| 246 void InfiniteCacheTransaction::OnRequestStart(const HttpRequestInfo* request) { | 251 void InfiniteCacheTransaction::OnRequestStart(const HttpRequestInfo* request) { |
| 247 if (!cache_) | 252 if (!cache_) |
| 248 return; | 253 return; |
| 249 | 254 |
| 255 scoped_ptr<ResourceData> resource_data(new ResourceData); | |
|
rvargas (doing something else)
2012/09/29 02:12:51
there's no need for a local variable + swap. Just
willchan no longer on Chromium
2012/09/29 02:18:27
Done.
| |
| 250 std::string method = request->method; | 256 std::string method = request->method; |
| 251 if (method == "POST" || method == "DELETE" || method == "PUT") { | 257 if (method == "POST" || method == "DELETE" || method == "PUT") { |
| 252 must_doom_entry_ = true; | 258 resource_data->details.flags |= DOOM_METHOD; |
| 253 } else if (method != "GET") { | 259 } else if (method != "GET") { |
| 254 cache_.reset(); | 260 cache_.reset(); |
| 255 return; | 261 return; |
| 262 } else { | |
|
rvargas (doing something else)
2012/09/29 02:12:51
no need for an else
willchan no longer on Chromium
2012/09/29 02:18:27
Done.
| |
| 263 const std::string cache_key = HttpUtil::SpecForRequest(request->url); | |
|
rvargas (doing something else)
2012/09/29 02:12:51
cache_->GenerateKey(request)
| |
| 264 if (cache_key == kGaJsHttpUrl) { | |
| 265 resource_data->details.flags &= GA_JS_HTTP; | |
|
rvargas (doing something else)
2012/09/29 02:12:51
|= :)
willchan no longer on Chromium
2012/09/29 02:18:27
Fixed earlier! I saw the test failures, thank god
| |
| 266 } else if (cache_key == kGaJsHttpsUrl) { | |
| 267 resource_data->details.flags &= GA_JS_HTTPS; | |
| 268 } | |
| 256 } | 269 } |
| 257 | 270 |
| 258 resource_data_.reset(new ResourceData); | 271 resource_data_.swap(resource_data); |
| 259 CryptoHash(cache_->GenerateKey(request), &resource_data_->key); | 272 CryptoHash(cache_->GenerateKey(request), &resource_data_->key); |
|
rvargas (doing something else)
2012/09/29 02:12:51
use cache_key here
willchan no longer on Chromium
2012/09/29 02:18:27
Done.
| |
| 260 } | 273 } |
| 261 | 274 |
| 262 void InfiniteCacheTransaction::OnResponseReceived( | 275 void InfiniteCacheTransaction::OnResponseReceived( |
| 263 const HttpResponseInfo* response) { | 276 const HttpResponseInfo* response) { |
| 264 if (!cache_) | 277 if (!cache_) |
| 265 return; | 278 return; |
| 266 | 279 |
| 267 Details& details = resource_data_->details; | 280 Details& details = resource_data_->details; |
| 268 | 281 |
| 282 // Store the old ga.js flag values. | |
|
rvargas (doing something else)
2012/09/29 02:12:51
stale comment
willchan no longer on Chromium
2012/09/29 02:18:27
Done.
| |
| 283 const uint32 kPreserveFlagsBitMask = (GA_JS_HTTP | GA_JS_HTTPS | DOOM_METHOD); | |
| 284 uint32 old_flag_values = details.flags & kPreserveFlagsBitMask; | |
| 285 | |
| 269 details.expiration = GetExpiration(response); | 286 details.expiration = GetExpiration(response); |
| 270 details.last_access = TimeToInt(response->request_time); | 287 details.last_access = TimeToInt(response->request_time); |
| 271 details.flags = GetCacheability(response); | 288 details.flags = GetCacheability(response); |
| 272 details.vary_hash = GetVaryHash(response); | 289 details.vary_hash = GetVaryHash(response); |
| 273 details.response_hash = adler32(0, Z_NULL, 0); // Init the hash. | 290 details.response_hash = adler32(0, Z_NULL, 0); // Init the hash. |
| 274 | 291 |
| 275 if (!details.flags && | 292 if (!details.flags && |
| 276 TimeToInt(response->response_time) == details.expiration) { | 293 TimeToInt(response->response_time) == details.expiration) { |
| 277 details.flags = EXPIRED; | 294 details.flags = EXPIRED; |
| 278 } | 295 } |
| 296 | |
| 297 // Restore the old flag values we wanted to preserve. | |
| 298 details.flags |= old_flag_values; | |
| 299 | |
| 279 details.flags |= GetRevalidationFlags(response); | 300 details.flags |= GetRevalidationFlags(response); |
| 280 | 301 |
| 281 if (must_doom_entry_) | |
| 282 details.flags |= DOOM_METHOD; | |
| 283 | |
| 284 Pickle pickle; | 302 Pickle pickle; |
| 285 response->Persist(&pickle, true, false); // Skip transient headers. | 303 response->Persist(&pickle, true, false); // Skip transient headers. |
| 286 details.headers_size = pickle.size(); | 304 details.headers_size = pickle.size(); |
| 287 details.headers_hash = adler32(0, Z_NULL, 0); | 305 details.headers_hash = adler32(0, Z_NULL, 0); |
| 288 details.headers_hash = adler32(details.headers_hash, | 306 details.headers_hash = adler32(details.headers_hash, |
| 289 reinterpret_cast<const Bytef*>(pickle.data()), | 307 reinterpret_cast<const Bytef*>(pickle.data()), |
| 290 pickle.size()); | 308 pickle.size()); |
| 291 } | 309 } |
| 292 | 310 |
| 293 void InfiniteCacheTransaction::OnDataRead(const char* data, int data_len) { | 311 void InfiniteCacheTransaction::OnDataRead(const char* data, int data_len) { |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 | 783 |
| 766 void InfiniteCache::Worker::UpdateSize(int old_size, int new_size) { | 784 void InfiniteCache::Worker::UpdateSize(int old_size, int new_size) { |
| 767 header_->total_size += new_size - old_size; | 785 header_->total_size += new_size - old_size; |
| 768 DCHECK_GE(header_->total_size, 0); | 786 DCHECK_GE(header_->total_size, 0); |
| 769 } | 787 } |
| 770 | 788 |
| 771 void InfiniteCache::Worker::RecordHit(const Details& old, Details* details) { | 789 void InfiniteCache::Worker::RecordHit(const Details& old, Details* details) { |
| 772 header_->num_hits++; | 790 header_->num_hits++; |
| 773 int access_delta = (IntToTime(details->last_access) - | 791 int access_delta = (IntToTime(details->last_access) - |
| 774 IntToTime(old.last_access)).InMinutes(); | 792 IntToTime(old.last_access)).InMinutes(); |
| 775 if (old.use_count) | 793 if (old.use_count) { |
| 776 UMA_HISTOGRAM_COUNTS("InfiniteCache.ReuseAge", access_delta); | 794 UMA_HISTOGRAM_COUNTS("InfiniteCache.ReuseAge", access_delta); |
| 777 else | 795 if (details->flags & GA_JS_HTTP) { |
| 796 UMA_HISTOGRAM_COUNTS("InfiniteCache.GaJsHttpReuseAge", access_delta); | |
| 797 } else if (details->flags & GA_JS_HTTPS) { | |
| 798 UMA_HISTOGRAM_COUNTS("InfiniteCache.GaJsHttpsReuseAge", access_delta); | |
| 799 } | |
| 800 } else { | |
| 778 UMA_HISTOGRAM_COUNTS("InfiniteCache.FirstReuseAge", access_delta); | 801 UMA_HISTOGRAM_COUNTS("InfiniteCache.FirstReuseAge", access_delta); |
| 802 if (details->flags & GA_JS_HTTP) { | |
| 803 UMA_HISTOGRAM_COUNTS( | |
| 804 "InfiniteCache.GaJsHttpFirstReuseAge", access_delta); | |
| 805 } else if (details->flags & GA_JS_HTTPS) { | |
| 806 UMA_HISTOGRAM_COUNTS( | |
| 807 "InfiniteCache.GaJsHttpsFirstReuseAge", access_delta); | |
| 808 } | |
| 809 } | |
| 779 | 810 |
| 780 details->use_count = old.use_count; | 811 details->use_count = old.use_count; |
| 781 if (details->use_count < kuint8max) | 812 if (details->use_count < kuint8max) |
| 782 details->use_count++; | 813 details->use_count++; |
| 783 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.UseCount", details->use_count, 0, | 814 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.UseCount", details->use_count, 0, |
| 784 kuint8max, 25); | 815 kuint8max, 25); |
| 816 if (details->flags & GA_JS_HTTP) { | |
| 817 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.GaJsHttpUseCount", | |
| 818 details->use_count, 0, kuint8max, 25); | |
| 819 } else if (details->flags & GA_JS_HTTPS) { | |
| 820 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.GaJsHttpsUseCount", | |
| 821 details->use_count, 0, kuint8max, 25); | |
| 822 } | |
| 785 } | 823 } |
| 786 | 824 |
| 787 void InfiniteCache::Worker::RecordUpdate(const Details& old, Details* details) { | 825 void InfiniteCache::Worker::RecordUpdate(const Details& old, Details* details) { |
| 788 int access_delta = (IntToTime(details->last_access) - | 826 int access_delta = (IntToTime(details->last_access) - |
| 789 IntToTime(old.last_access)).InMinutes(); | 827 IntToTime(old.last_access)).InMinutes(); |
| 790 if (old.update_count) | 828 if (old.update_count) { |
| 791 UMA_HISTOGRAM_COUNTS("InfiniteCache.UpdateAge", access_delta); | 829 UMA_HISTOGRAM_COUNTS("InfiniteCache.UpdateAge", access_delta); |
| 792 else | 830 if (details->flags & GA_JS_HTTP) { |
| 831 UMA_HISTOGRAM_COUNTS( | |
| 832 "InfiniteCache.GaJsHttpUpdateAge", access_delta); | |
| 833 } else if (details->flags & GA_JS_HTTPS) { | |
| 834 UMA_HISTOGRAM_COUNTS( | |
| 835 "InfiniteCache.GaJsHttpsUpdateAge", access_delta); | |
| 836 } | |
| 837 } else { | |
| 793 UMA_HISTOGRAM_COUNTS("InfiniteCache.FirstUpdateAge", access_delta); | 838 UMA_HISTOGRAM_COUNTS("InfiniteCache.FirstUpdateAge", access_delta); |
| 839 if (details->flags & GA_JS_HTTP) { | |
| 840 UMA_HISTOGRAM_COUNTS( | |
| 841 "InfiniteCache.GaJsHttpFirstUpdateAge", access_delta); | |
| 842 } else if (details->flags & GA_JS_HTTPS) { | |
| 843 UMA_HISTOGRAM_COUNTS( | |
| 844 "InfiniteCache.GaJsHttpsFirstUpdateAge", access_delta); | |
| 845 } | |
| 846 } | |
| 794 | 847 |
| 795 details->update_count = old.update_count; | 848 details->update_count = old.update_count; |
| 796 if (details->update_count < kuint8max) | 849 if (details->update_count < kuint8max) |
| 797 details->update_count++; | 850 details->update_count++; |
| 798 | 851 |
| 799 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.UpdateCount", | 852 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.UpdateCount", |
| 800 details->update_count, 0, kuint8max, 25); | 853 details->update_count, 0, kuint8max, 25); |
| 854 if (details->flags & GA_JS_HTTP) { | |
| 855 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.GaJsHttpUpdateCount", | |
| 856 details->update_count, 0, kuint8max, 25); | |
| 857 } else if (details->flags & GA_JS_HTTPS) { | |
| 858 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.GaJsHttpsUpdateCount", | |
| 859 details->update_count, 0, kuint8max, 25); | |
| 860 } | |
| 801 details->use_count = 0; | 861 details->use_count = 0; |
| 802 } | 862 } |
| 803 | 863 |
| 804 void InfiniteCache::Worker::GenerateHistograms() { | 864 void InfiniteCache::Worker::GenerateHistograms() { |
| 805 bool new_size_step = (header_->total_size / kReportSizeStep != | 865 bool new_size_step = (header_->total_size / kReportSizeStep != |
| 806 header_->size_last_report / kReportSizeStep); | 866 header_->size_last_report / kReportSizeStep); |
| 807 header_->size_last_report = header_->total_size; | 867 header_->size_last_report = header_->total_size; |
| 808 if (!new_size_step && (header_->use_minutes % 60 != 0)) | 868 if (!new_size_step && (header_->use_minutes % 60 != 0)) |
| 809 return; | 869 return; |
| 810 | 870 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 reason = REUSE_TRUNCATED; | 943 reason = REUSE_TRUNCATED; |
| 884 | 944 |
| 885 if (old.vary_hash != current.vary_hash) | 945 if (old.vary_hash != current.vary_hash) |
| 886 reason = REUSE_VARY; | 946 reason = REUSE_VARY; |
| 887 | 947 |
| 888 bool have_to_drop = (old.flags & TRUNCATED) && !(old.flags & RESUMABLE); | 948 bool have_to_drop = (old.flags & TRUNCATED) && !(old.flags & RESUMABLE); |
| 889 if (reason && (old.flags & REVALIDATEABLE) && !have_to_drop) | 949 if (reason && (old.flags & REVALIDATEABLE) && !have_to_drop) |
| 890 reason += REUSE_REVALIDATEABLE; | 950 reason += REUSE_REVALIDATEABLE; |
| 891 | 951 |
| 892 UMA_HISTOGRAM_ENUMERATION("InfiniteCache.ReuseFailure", reason, 15); | 952 UMA_HISTOGRAM_ENUMERATION("InfiniteCache.ReuseFailure", reason, 15); |
| 953 if (current.flags & GA_JS_HTTP) { | |
| 954 UMA_HISTOGRAM_ENUMERATION( | |
| 955 "InfiniteCache.GaJsHttpReuseFailure", reason, 15); | |
| 956 } else if (current.flags & GA_JS_HTTPS) { | |
| 957 UMA_HISTOGRAM_ENUMERATION( | |
| 958 "InfiniteCache.GaJsHttpsReuseFailure", reason, 15); | |
| 959 } | |
| 893 return !reason; | 960 return !reason; |
| 894 } | 961 } |
| 895 | 962 |
| 896 bool InfiniteCache::Worker::DataChanged(const Details& old, | 963 bool InfiniteCache::Worker::DataChanged(const Details& old, |
| 897 const Details& current) { | 964 const Details& current) { |
| 898 if (current.flags & CACHED) | 965 if (current.flags & CACHED) |
| 899 return false; | 966 return false; |
| 900 | 967 |
| 901 bool changed = false; | 968 bool changed = false; |
| 902 if (old.response_size != current.response_size) { | 969 if (old.response_size != current.response_size) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1014 int InfiniteCache::FlushDataForTest(const CompletionCallback& callback) { | 1081 int InfiniteCache::FlushDataForTest(const CompletionCallback& callback) { |
| 1015 DCHECK(worker_); | 1082 DCHECK(worker_); |
| 1016 int* result = new int; | 1083 int* result = new int; |
| 1017 task_runner_->PostTaskAndReply( | 1084 task_runner_->PostTaskAndReply( |
| 1018 FROM_HERE, base::Bind(&InfiniteCache::Worker::Flush, worker_, result), | 1085 FROM_HERE, base::Bind(&InfiniteCache::Worker::Flush, worker_, result), |
| 1019 base::Bind(&OnComplete, callback, base::Owned(result))); | 1086 base::Bind(&OnComplete, callback, base::Owned(result))); |
| 1020 return net::ERR_IO_PENDING; | 1087 return net::ERR_IO_PENDING; |
| 1021 } | 1088 } |
| 1022 | 1089 |
| 1023 } // namespace net | 1090 } // namespace net |
| OLD | NEW |