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 = 1 << 8, | |
| 50 GA_JS_HTTPS = 1 << 9, // 0 means HTTP, 1 means HTTPS | |
| 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"; | |
| 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()), must_doom_entry_(false) { |
| 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); | |
| 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 must_doom_entry_ = true; |
| 253 } else if (method != "GET") { | 259 } else if (method != "GET") { |
| 254 cache_.reset(); | 260 cache_.reset(); |
| 255 return; | 261 return; |
| 262 } else { | |
| 263 const std::string cache_key = HttpUtil::SpecForRequest(request->url); | |
| 264 if (cache_key == kGaJsHttpUrl) { | |
| 265 resource_data_->details.flags &= GA_JS; | |
| 266 } else if (cache_key == kGaJsHttpsUrl) { | |
| 267 resource_data_->details.flags &= GA_JS | GA_JS_HTTPS; | |
| 268 } | |
| 256 } | 269 } |
| 257 | 270 |
| 258 resource_data_.reset(new ResourceData); | 271 resource_data_.swap(resource_data); |
|
rvargas (doing something else)
2012/09/28 21:51:15
move this line up to line 250 (in this version).
willchan no longer on Chromium
2012/09/28 22:07:55
I'm fine with that, but in the method != "GET" cas
| |
| 259 CryptoHash(cache_->GenerateKey(request), &resource_data_->key); | 272 CryptoHash(cache_->GenerateKey(request), &resource_data_->key); |
| 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. | |
| 283 const uint32 kGaJsBitMask = (GA_JS|GA_JS_HTTPS); | |
| 284 uint32 old_ga_js_values = details.flags & kGaJsBitMask; | |
| 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 ga.js flag values. | |
| 298 details.flags |= old_ga_js_values; | |
|
rvargas (doing something else)
2012/09/28 21:51:15
I knew there was a reason for passing DOOM_METHOD
willchan no longer on Chromium
2012/09/28 22:07:55
I don't get it...why?
| |
| 299 | |
| 279 details.flags |= GetRevalidationFlags(response); | 300 details.flags |= GetRevalidationFlags(response); |
| 280 | 301 |
| 281 if (must_doom_entry_) | 302 if (must_doom_entry_) |
| 282 details.flags |= DOOM_METHOD; | 303 details.flags |= DOOM_METHOD; |
| 283 | 304 |
| 284 Pickle pickle; | 305 Pickle pickle; |
| 285 response->Persist(&pickle, true, false); // Skip transient headers. | 306 response->Persist(&pickle, true, false); // Skip transient headers. |
| 286 details.headers_size = pickle.size(); | 307 details.headers_size = pickle.size(); |
| 287 details.headers_hash = adler32(0, Z_NULL, 0); | 308 details.headers_hash = adler32(0, Z_NULL, 0); |
| 288 details.headers_hash = adler32(details.headers_hash, | 309 details.headers_hash = adler32(details.headers_hash, |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 | 786 |
| 766 void InfiniteCache::Worker::UpdateSize(int old_size, int new_size) { | 787 void InfiniteCache::Worker::UpdateSize(int old_size, int new_size) { |
| 767 header_->total_size += new_size - old_size; | 788 header_->total_size += new_size - old_size; |
| 768 DCHECK_GE(header_->total_size, 0); | 789 DCHECK_GE(header_->total_size, 0); |
| 769 } | 790 } |
| 770 | 791 |
| 771 void InfiniteCache::Worker::RecordHit(const Details& old, Details* details) { | 792 void InfiniteCache::Worker::RecordHit(const Details& old, Details* details) { |
| 772 header_->num_hits++; | 793 header_->num_hits++; |
| 773 int access_delta = (IntToTime(details->last_access) - | 794 int access_delta = (IntToTime(details->last_access) - |
| 774 IntToTime(old.last_access)).InMinutes(); | 795 IntToTime(old.last_access)).InMinutes(); |
| 775 if (old.use_count) | 796 if (old.use_count) { |
| 776 UMA_HISTOGRAM_COUNTS("InfiniteCache.ReuseAge", access_delta); | 797 UMA_HISTOGRAM_COUNTS("InfiniteCache.ReuseAge", access_delta); |
| 777 else | 798 if (details->flags & GA_JS) { |
| 799 if (details->flags & GA_JS_HTTPS) { | |
| 800 UMA_HISTOGRAM_COUNTS("InfiniteCache.GaJsHttpsReuseAge", access_delta); | |
| 801 } else { | |
| 802 UMA_HISTOGRAM_COUNTS("InfiniteCache.GaJsHttpReuseAge", access_delta); | |
| 803 } | |
| 804 } | |
| 805 } else { | |
| 778 UMA_HISTOGRAM_COUNTS("InfiniteCache.FirstReuseAge", access_delta); | 806 UMA_HISTOGRAM_COUNTS("InfiniteCache.FirstReuseAge", access_delta); |
| 807 if (details->flags & GA_JS) { | |
| 808 if (details->flags & GA_JS_HTTPS) { | |
| 809 UMA_HISTOGRAM_COUNTS( | |
| 810 "InfiniteCache.GaJsHttpsFirstReuseAge", access_delta); | |
| 811 } else { | |
| 812 UMA_HISTOGRAM_COUNTS( | |
| 813 "InfiniteCache.GaJsHttpFirstReuseAge", access_delta); | |
| 814 } | |
| 815 } | |
| 816 } | |
| 779 | 817 |
| 780 details->use_count = old.use_count; | 818 details->use_count = old.use_count; |
| 781 if (details->use_count < kuint8max) | 819 if (details->use_count < kuint8max) |
| 782 details->use_count++; | 820 details->use_count++; |
| 783 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.UseCount", details->use_count, 0, | 821 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.UseCount", details->use_count, 0, |
| 784 kuint8max, 25); | 822 kuint8max, 25); |
| 823 if (details->flags & GA_JS) { | |
| 824 if (details->flags & GA_JS_HTTPS) { | |
| 825 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.GaJsHttpsUseCount", | |
| 826 details->use_count, 0, kuint8max, 25); | |
| 827 } else { | |
| 828 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.GaJsHttpUseCount", | |
| 829 details->use_count, 0, kuint8max, 25); | |
| 830 } | |
| 831 } | |
| 785 } | 832 } |
| 786 | 833 |
| 787 void InfiniteCache::Worker::RecordUpdate(const Details& old, Details* details) { | 834 void InfiniteCache::Worker::RecordUpdate(const Details& old, Details* details) { |
| 788 int access_delta = (IntToTime(details->last_access) - | 835 int access_delta = (IntToTime(details->last_access) - |
| 789 IntToTime(old.last_access)).InMinutes(); | 836 IntToTime(old.last_access)).InMinutes(); |
| 790 if (old.update_count) | 837 if (old.update_count) { |
| 791 UMA_HISTOGRAM_COUNTS("InfiniteCache.UpdateAge", access_delta); | 838 UMA_HISTOGRAM_COUNTS("InfiniteCache.UpdateAge", access_delta); |
| 792 else | 839 if (details->flags & GA_JS) { |
| 840 if (details->flags & GA_JS_HTTPS) { | |
| 841 UMA_HISTOGRAM_COUNTS( | |
| 842 "InfiniteCache.GaJsHttpsUpdateAge", access_delta); | |
| 843 } else { | |
| 844 UMA_HISTOGRAM_COUNTS( | |
| 845 "InfiniteCache.GaJsHttpUpdateAge", access_delta); | |
| 846 } | |
| 847 } | |
| 848 } else { | |
| 793 UMA_HISTOGRAM_COUNTS("InfiniteCache.FirstUpdateAge", access_delta); | 849 UMA_HISTOGRAM_COUNTS("InfiniteCache.FirstUpdateAge", access_delta); |
| 850 if (details->flags & GA_JS) { | |
| 851 if (details->flags & GA_JS_HTTPS) { | |
| 852 UMA_HISTOGRAM_COUNTS( | |
| 853 "InfiniteCache.GaJsHttpsFirstUpdateAge", access_delta); | |
| 854 } else { | |
| 855 UMA_HISTOGRAM_COUNTS( | |
| 856 "InfiniteCache.GaJsHttpFirstUpdateAge", access_delta); | |
| 857 } | |
| 858 } | |
| 859 } | |
| 794 | 860 |
| 795 details->update_count = old.update_count; | 861 details->update_count = old.update_count; |
| 796 if (details->update_count < kuint8max) | 862 if (details->update_count < kuint8max) |
| 797 details->update_count++; | 863 details->update_count++; |
| 798 | 864 |
| 799 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.UpdateCount", | 865 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.UpdateCount", |
| 800 details->update_count, 0, kuint8max, 25); | 866 details->update_count, 0, kuint8max, 25); |
| 867 if (details->flags & GA_JS) { | |
| 868 if (details->flags & GA_JS_HTTPS) { | |
| 869 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.GaJsHttpsUpdateCount", | |
| 870 details->update_count, 0, kuint8max, 25); | |
| 871 } else { | |
| 872 UMA_HISTOGRAM_CUSTOM_COUNTS("InfiniteCache.GaJsHttpUpdateCount", | |
| 873 details->update_count, 0, kuint8max, 25); | |
| 874 } | |
| 875 } | |
| 801 details->use_count = 0; | 876 details->use_count = 0; |
| 802 } | 877 } |
| 803 | 878 |
| 804 void InfiniteCache::Worker::GenerateHistograms() { | 879 void InfiniteCache::Worker::GenerateHistograms() { |
| 805 bool new_size_step = (header_->total_size / kReportSizeStep != | 880 bool new_size_step = (header_->total_size / kReportSizeStep != |
| 806 header_->size_last_report / kReportSizeStep); | 881 header_->size_last_report / kReportSizeStep); |
| 807 header_->size_last_report = header_->total_size; | 882 header_->size_last_report = header_->total_size; |
| 808 if (!new_size_step && (header_->use_minutes % 60 != 0)) | 883 if (!new_size_step && (header_->use_minutes % 60 != 0)) |
| 809 return; | 884 return; |
| 810 | 885 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 reason = REUSE_TRUNCATED; | 958 reason = REUSE_TRUNCATED; |
| 884 | 959 |
| 885 if (old.vary_hash != current.vary_hash) | 960 if (old.vary_hash != current.vary_hash) |
| 886 reason = REUSE_VARY; | 961 reason = REUSE_VARY; |
| 887 | 962 |
| 888 bool have_to_drop = (old.flags & TRUNCATED) && !(old.flags & RESUMABLE); | 963 bool have_to_drop = (old.flags & TRUNCATED) && !(old.flags & RESUMABLE); |
| 889 if (reason && (old.flags & REVALIDATEABLE) && !have_to_drop) | 964 if (reason && (old.flags & REVALIDATEABLE) && !have_to_drop) |
| 890 reason += REUSE_REVALIDATEABLE; | 965 reason += REUSE_REVALIDATEABLE; |
| 891 | 966 |
| 892 UMA_HISTOGRAM_ENUMERATION("InfiniteCache.ReuseFailure", reason, 15); | 967 UMA_HISTOGRAM_ENUMERATION("InfiniteCache.ReuseFailure", reason, 15); |
| 968 if (current.flags & GA_JS) { | |
| 969 if (current.flags & GA_JS_HTTPS) { | |
| 970 UMA_HISTOGRAM_ENUMERATION( | |
| 971 "InfiniteCache.GaJsHttpsReuseFailure", reason, 15); | |
| 972 } else { | |
| 973 UMA_HISTOGRAM_ENUMERATION( | |
| 974 "InfiniteCache.GaJsHttpReuseFailure", reason, 15); | |
| 975 } | |
| 976 } | |
| 893 return !reason; | 977 return !reason; |
| 894 } | 978 } |
| 895 | 979 |
| 896 bool InfiniteCache::Worker::DataChanged(const Details& old, | 980 bool InfiniteCache::Worker::DataChanged(const Details& old, |
| 897 const Details& current) { | 981 const Details& current) { |
| 898 if (current.flags & CACHED) | 982 if (current.flags & CACHED) |
| 899 return false; | 983 return false; |
| 900 | 984 |
| 901 bool changed = false; | 985 bool changed = false; |
| 902 if (old.response_size != current.response_size) { | 986 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) { | 1098 int InfiniteCache::FlushDataForTest(const CompletionCallback& callback) { |
| 1015 DCHECK(worker_); | 1099 DCHECK(worker_); |
| 1016 int* result = new int; | 1100 int* result = new int; |
| 1017 task_runner_->PostTaskAndReply( | 1101 task_runner_->PostTaskAndReply( |
| 1018 FROM_HERE, base::Bind(&InfiniteCache::Worker::Flush, worker_, result), | 1102 FROM_HERE, base::Bind(&InfiniteCache::Worker::Flush, worker_, result), |
| 1019 base::Bind(&OnComplete, callback, base::Owned(result))); | 1103 base::Bind(&OnComplete, callback, base::Owned(result))); |
| 1020 return net::ERR_IO_PENDING; | 1104 return net::ERR_IO_PENDING; |
| 1021 } | 1105 } |
| 1022 | 1106 |
| 1023 } // namespace net | 1107 } // namespace net |
| OLD | NEW |