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 "chrome/browser/net/predictor.h" | 5 #include "chrome/browser/net/predictor.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <set> | 9 #include <set> |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 const int Predictor::kMaxUnusedSocketLifetimeSecondsWithoutAGet = 10; | 80 const int Predictor::kMaxUnusedSocketLifetimeSecondsWithoutAGet = 10; |
81 // To control our congestion avoidance system, which discards a queue when | 81 // To control our congestion avoidance system, which discards a queue when |
82 // resolutions are "taking too long," we need an expected resolution time. | 82 // resolutions are "taking too long," we need an expected resolution time. |
83 // Common average is in the range of 300-500ms. | 83 // Common average is in the range of 300-500ms. |
84 const int kExpectedResolutionTimeMs = 500; | 84 const int kExpectedResolutionTimeMs = 500; |
85 const int Predictor::kTypicalSpeculativeGroupSize = 8; | 85 const int Predictor::kTypicalSpeculativeGroupSize = 8; |
86 const int Predictor::kMaxSpeculativeResolveQueueDelayMs = | 86 const int Predictor::kMaxSpeculativeResolveQueueDelayMs = |
87 (kExpectedResolutionTimeMs * Predictor::kTypicalSpeculativeGroupSize) / | 87 (kExpectedResolutionTimeMs * Predictor::kTypicalSpeculativeGroupSize) / |
88 Predictor::kMaxSpeculativeParallelResolves; | 88 Predictor::kMaxSpeculativeParallelResolves; |
89 | 89 |
90 // The default value of the credentials flag when preconnecting. | |
91 static bool kAllowCredentialsOnPreconnectByDefault = true; | |
Ryan Sleevi
2015/07/10 09:46:45
I'm still not sure why this static bool. When I re
Yoav Weiss
2015/07/10 10:03:40
Yes, it is just about re-using the constant.
| |
92 | |
90 static int g_max_queueing_delay_ms = | 93 static int g_max_queueing_delay_ms = |
91 Predictor::kMaxSpeculativeResolveQueueDelayMs; | 94 Predictor::kMaxSpeculativeResolveQueueDelayMs; |
92 static size_t g_max_parallel_resolves = | 95 static size_t g_max_parallel_resolves = |
93 Predictor::kMaxSpeculativeParallelResolves; | 96 Predictor::kMaxSpeculativeParallelResolves; |
94 | 97 |
95 // A version number for prefs that are saved. This should be incremented when | 98 // A version number for prefs that are saved. This should be incremented when |
96 // we change the format so that we discard old data. | 99 // we change the format so that we discard old data. |
97 static const int kPredictorStartupFormatVersion = 1; | 100 static const int kPredictorStartupFormatVersion = 1; |
98 | 101 |
99 class Predictor::LookupRequest { | 102 class Predictor::LookupRequest { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
258 // pool. Currently, we just do a connect, which MAY be reset if we | 261 // pool. Currently, we just do a connect, which MAY be reset if we |
259 // don't use it in 10 secondes!!! As a result, we may do more | 262 // don't use it in 10 secondes!!! As a result, we may do more |
260 // connections, and actually cost the server more than if we did a real | 263 // connections, and actually cost the server more than if we did a real |
261 // get with a fake request (/gen_204 might be the good path on Google). | 264 // get with a fake request (/gen_204 might be the good path on Google). |
262 const int kMaxSearchKeepaliveSeconds(10); | 265 const int kMaxSearchKeepaliveSeconds(10); |
263 if ((now - last_omnibox_preconnect_).InSeconds() < | 266 if ((now - last_omnibox_preconnect_).InSeconds() < |
264 kMaxSearchKeepaliveSeconds) | 267 kMaxSearchKeepaliveSeconds) |
265 return; // We've done a preconnect recently. | 268 return; // We've done a preconnect recently. |
266 last_omnibox_preconnect_ = now; | 269 last_omnibox_preconnect_ = now; |
267 const int kConnectionsNeeded = 1; | 270 const int kConnectionsNeeded = 1; |
268 PreconnectUrl( | 271 PreconnectUrl(CanonicalizeUrl(url), GURL(), motivation, |
269 CanonicalizeUrl(url), GURL(), motivation, kConnectionsNeeded); | 272 kConnectionsNeeded, |
273 kAllowCredentialsOnPreconnectByDefault); | |
270 return; // Skip pre-resolution, since we'll open a connection. | 274 return; // Skip pre-resolution, since we'll open a connection. |
271 } | 275 } |
272 } else { | 276 } else { |
273 consecutive_omnibox_preconnect_count_ = 0; | 277 consecutive_omnibox_preconnect_count_ = 0; |
274 } | 278 } |
275 } | 279 } |
276 | 280 |
277 // Fall through and consider pre-resolution. | 281 // Fall through and consider pre-resolution. |
278 | 282 |
279 // Omnibox tends to call in pairs (just a few milliseconds apart), and we | 283 // Omnibox tends to call in pairs (just a few milliseconds apart), and we |
(...skipping 18 matching lines...) Expand all Loading... | |
298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 302 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
299 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 303 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
300 if (!predictor_enabled_ || !preconnect_enabled_ || | 304 if (!predictor_enabled_ || !preconnect_enabled_ || |
301 !url.is_valid() || !url.has_host()) | 305 !url.is_valid() || !url.has_host()) |
302 return; | 306 return; |
303 if (!CanPreresolveAndPreconnect()) | 307 if (!CanPreresolveAndPreconnect()) |
304 return; | 308 return; |
305 | 309 |
306 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); | 310 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); |
307 const int kConnectionsNeeded = 1; | 311 const int kConnectionsNeeded = 1; |
308 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, | 312 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, motivation, |
309 motivation, kConnectionsNeeded); | 313 kConnectionsNeeded, kAllowCredentialsOnPreconnectByDefault); |
310 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); | 314 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); |
311 } | 315 } |
312 | 316 |
313 UrlList Predictor::GetPredictedUrlListAtStartup( | 317 UrlList Predictor::GetPredictedUrlListAtStartup( |
314 PrefService* user_prefs, | 318 PrefService* user_prefs, |
315 PrefService* local_state) { | 319 PrefService* local_state) { |
316 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 320 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
317 UrlList urls; | 321 UrlList urls; |
318 // Recall list of URLs we learned about during last session. | 322 // Recall list of URLs we learned about during last session. |
319 // This may catch secondary hostnames, pulled in by the homepages. It will | 323 // This may catch secondary hostnames, pulled in by the homepages. It will |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
833 // a frequent occurrence on Android. | 837 // a frequent occurrence on Android. |
834 TrimReferrersNow(); | 838 TrimReferrersNow(); |
835 SerializeReferrers(referral_list); | 839 SerializeReferrers(referral_list); |
836 | 840 |
837 completion->Signal(); | 841 completion->Signal(); |
838 } | 842 } |
839 | 843 |
840 void Predictor::PreconnectUrl(const GURL& url, | 844 void Predictor::PreconnectUrl(const GURL& url, |
841 const GURL& first_party_for_cookies, | 845 const GURL& first_party_for_cookies, |
842 UrlInfo::ResolutionMotivation motivation, | 846 UrlInfo::ResolutionMotivation motivation, |
843 int count) { | 847 int count, |
848 bool allow_credentials) { | |
844 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 849 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
845 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 850 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
846 | 851 |
847 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 852 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
848 PreconnectUrlOnIOThread(url, first_party_for_cookies, motivation, count); | 853 PreconnectUrlOnIOThread(url, first_party_for_cookies, motivation, count, |
854 allow_credentials); | |
849 } else { | 855 } else { |
850 BrowserThread::PostTask( | 856 BrowserThread::PostTask( |
851 BrowserThread::IO, | 857 BrowserThread::IO, FROM_HERE, |
852 FROM_HERE, | 858 base::Bind(&Predictor::PreconnectUrlOnIOThread, base::Unretained(this), |
853 base::Bind(&Predictor::PreconnectUrlOnIOThread, | 859 url, first_party_for_cookies, motivation, count, |
854 base::Unretained(this), url, first_party_for_cookies, | 860 allow_credentials)); |
855 motivation, count)); | |
856 } | 861 } |
857 } | 862 } |
858 | 863 |
859 void Predictor::PreconnectUrlOnIOThread( | 864 void Predictor::PreconnectUrlOnIOThread( |
860 const GURL& original_url, | 865 const GURL& original_url, |
861 const GURL& first_party_for_cookies, | 866 const GURL& first_party_for_cookies, |
862 UrlInfo::ResolutionMotivation motivation, | 867 UrlInfo::ResolutionMotivation motivation, |
863 int count) { | 868 int count, |
869 bool allow_credentials) { | |
864 // Skip the HSTS redirect. | 870 // Skip the HSTS redirect. |
865 GURL url = GetHSTSRedirectOnIOThread(original_url); | 871 GURL url = GetHSTSRedirectOnIOThread(original_url); |
866 | 872 |
867 if (observer_) { | 873 if (observer_) { |
868 observer_->OnPreconnectUrl( | 874 observer_->OnPreconnectUrl( |
869 url, first_party_for_cookies, motivation, count); | 875 url, first_party_for_cookies, motivation, count); |
870 } | 876 } |
871 | 877 |
872 PreconnectOnIOThread(url, | 878 PreconnectOnIOThread(url, first_party_for_cookies, motivation, count, |
873 first_party_for_cookies, | 879 url_request_context_getter_.get(), allow_credentials); |
874 motivation, | |
875 count, | |
876 url_request_context_getter_.get()); | |
877 } | 880 } |
878 | 881 |
879 void Predictor::PredictFrameSubresources(const GURL& url, | 882 void Predictor::PredictFrameSubresources(const GURL& url, |
880 const GURL& first_party_for_cookies) { | 883 const GURL& first_party_for_cookies) { |
881 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 884 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
882 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 885 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
883 if (!predictor_enabled_) | 886 if (!predictor_enabled_) |
884 return; | 887 return; |
885 if (!CanPreresolveAndPreconnect()) | 888 if (!CanPreresolveAndPreconnect()) |
886 return; | 889 return; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
934 Referrers::iterator it = referrers_.find(url); | 937 Referrers::iterator it = referrers_.find(url); |
935 if (referrers_.end() == it) { | 938 if (referrers_.end() == it) { |
936 // Only when we don't know anything about this url, make 2 connections | 939 // Only when we don't know anything about this url, make 2 connections |
937 // available. We could do this completely via learning (by prepopulating | 940 // available. We could do this completely via learning (by prepopulating |
938 // the referrer_ list with this expected value), but it would swell the | 941 // the referrer_ list with this expected value), but it would swell the |
939 // size of the list with all the "Leaf" nodes in the tree (nodes that don't | 942 // size of the list with all the "Leaf" nodes in the tree (nodes that don't |
940 // load any subresources). If we learn about this resource, we will instead | 943 // load any subresources). If we learn about this resource, we will instead |
941 // provide a more carefully estimated preconnection count. | 944 // provide a more carefully estimated preconnection count. |
942 if (preconnect_enabled_) { | 945 if (preconnect_enabled_) { |
943 PreconnectUrlOnIOThread(url, first_party_for_cookies, | 946 PreconnectUrlOnIOThread(url, first_party_for_cookies, |
944 UrlInfo::SELF_REFERAL_MOTIVATED, 2); | 947 UrlInfo::SELF_REFERAL_MOTIVATED, 2, |
948 kAllowCredentialsOnPreconnectByDefault); | |
945 } | 949 } |
946 return; | 950 return; |
947 } | 951 } |
948 | 952 |
949 Referrer* referrer = &(it->second); | 953 Referrer* referrer = &(it->second); |
950 referrer->IncrementUseCount(); | 954 referrer->IncrementUseCount(); |
951 const UrlInfo::ResolutionMotivation motivation = | 955 const UrlInfo::ResolutionMotivation motivation = |
952 UrlInfo::LEARNED_REFERAL_MOTIVATED; | 956 UrlInfo::LEARNED_REFERAL_MOTIVATED; |
953 for (Referrer::iterator future_url = referrer->begin(); | 957 for (Referrer::iterator future_url = referrer->begin(); |
954 future_url != referrer->end(); ++future_url) { | 958 future_url != referrer->end(); ++future_url) { |
955 SubresourceValue evalution(TOO_NEW); | 959 SubresourceValue evalution(TOO_NEW); |
956 double connection_expectation = future_url->second.subresource_use_rate(); | 960 double connection_expectation = future_url->second.subresource_use_rate(); |
957 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation", | 961 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation", |
958 static_cast<int>(connection_expectation * 100), | 962 static_cast<int>(connection_expectation * 100), |
959 10, 5000, 50); | 963 10, 5000, 50); |
960 future_url->second.ReferrerWasObserved(); | 964 future_url->second.ReferrerWasObserved(); |
961 if (preconnect_enabled_ && | 965 if (preconnect_enabled_ && |
962 connection_expectation > kPreconnectWorthyExpectedValue) { | 966 connection_expectation > kPreconnectWorthyExpectedValue) { |
963 evalution = PRECONNECTION; | 967 evalution = PRECONNECTION; |
964 future_url->second.IncrementPreconnectionCount(); | 968 future_url->second.IncrementPreconnectionCount(); |
965 int count = static_cast<int>(std::ceil(connection_expectation)); | 969 int count = static_cast<int>(std::ceil(connection_expectation)); |
966 if (url.host() == future_url->first.host()) | 970 if (url.host() == future_url->first.host()) |
967 ++count; | 971 ++count; |
968 PreconnectUrlOnIOThread(future_url->first, first_party_for_cookies, | 972 PreconnectUrlOnIOThread(future_url->first, first_party_for_cookies, |
969 motivation, count); | 973 motivation, count, |
974 kAllowCredentialsOnPreconnectByDefault); | |
970 } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) { | 975 } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) { |
971 evalution = PRERESOLUTION; | 976 evalution = PRERESOLUTION; |
972 future_url->second.preresolution_increment(); | 977 future_url->second.preresolution_increment(); |
973 UrlInfo* queued_info = AppendToResolutionQueue(future_url->first, | 978 UrlInfo* queued_info = AppendToResolutionQueue(future_url->first, |
974 motivation); | 979 motivation); |
975 if (queued_info) | 980 if (queued_info) |
976 queued_info->SetReferringHostname(url); | 981 queued_info->SetReferringHostname(url); |
977 } | 982 } |
978 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution, | 983 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution, |
979 SUBRESOURCE_VALUE_MAX); | 984 SUBRESOURCE_VALUE_MAX); |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1318 } | 1323 } |
1319 | 1324 |
1320 void SimplePredictor::ShutdownOnUIThread() { | 1325 void SimplePredictor::ShutdownOnUIThread() { |
1321 SetShutdown(true); | 1326 SetShutdown(true); |
1322 } | 1327 } |
1323 | 1328 |
1324 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } | 1329 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } |
1325 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } | 1330 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } |
1326 | 1331 |
1327 } // namespace chrome_browser_net | 1332 } // namespace chrome_browser_net |
OLD | NEW |