| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
|  | 2 // Use of this source code is governed by a BSD-style license that can be | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 #include "net/url_request/url_request_backoff_manager.h" | 
|  | 6 | 
|  | 7 #include "base/logging.h" | 
|  | 8 #include "base/strings/string_number_conversions.h" | 
|  | 9 #include "base/strings/string_piece.h" | 
|  | 10 #include "base/strings/string_util.h" | 
|  | 11 #include "net/http/http_response_headers.h" | 
|  | 12 | 
|  | 13 namespace net { | 
|  | 14 | 
|  | 15 const uint16 URLRequestBackoffManager::kMinimumBackoffInSeconds = 1; | 
|  | 16 const uint16 URLRequestBackoffManager::kMaximumBackoffInSeconds = 50000; | 
|  | 17 const uint16 URLRequestBackoffManager::kNewEntriesBetweenCollecting = 200; | 
|  | 18 | 
|  | 19 URLRequestBackoffManager::URLRequestBackoffManager() | 
|  | 20     : new_entries_since_last_gc_(0) { | 
|  | 21   url_id_replacements_.ClearPassword(); | 
|  | 22   url_id_replacements_.ClearUsername(); | 
|  | 23   url_id_replacements_.ClearQuery(); | 
|  | 24   url_id_replacements_.ClearRef(); | 
|  | 25 | 
|  | 26   NetworkChangeNotifier::AddIPAddressObserver(this); | 
|  | 27   NetworkChangeNotifier::AddConnectionTypeObserver(this); | 
|  | 28 } | 
|  | 29 | 
|  | 30 URLRequestBackoffManager::~URLRequestBackoffManager() { | 
|  | 31   NetworkChangeNotifier::RemoveIPAddressObserver(this); | 
|  | 32   NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 
|  | 33   for (UrlEntryMap::iterator it = url_entries_.begin(); | 
|  | 34        it != url_entries_.end(); ++it) { | 
|  | 35     delete it->second; | 
|  | 36   } | 
|  | 37   url_entries_.clear(); | 
|  | 38 } | 
|  | 39 | 
|  | 40 void URLRequestBackoffManager::UpdateWithResponse( | 
|  | 41     const GURL& url, | 
|  | 42     HttpResponseHeaders* headers, | 
|  | 43     const base::Time& response_time) { | 
|  | 44   CalledOnValidThread(); | 
|  | 45   base::TimeDelta result; | 
|  | 46   if (GetBackoffTime(headers, &result)) { | 
|  | 47     new_entries_since_last_gc_++; | 
|  | 48     std::string url_id = GetIdFromUrl(url); | 
|  | 49     url_entries_[url_id] = | 
|  | 50         new Entry(response_time + result, response_time + result * 1.1); | 
|  | 51     GarbageCollectEntriesIfNecessary(); | 
|  | 52   } | 
|  | 53 } | 
|  | 54 | 
|  | 55 bool URLRequestBackoffManager::ShouldRejectRequest( | 
|  | 56     const GURL& url, | 
|  | 57     const base::Time& request_time) { | 
|  | 58   CalledOnValidThread(); | 
|  | 59   std::string url_id = GetIdFromUrl(url); | 
|  | 60   UrlEntryMap::iterator it = url_entries_.find(url_id); | 
|  | 61   if (it == url_entries_.end()) | 
|  | 62     return false; | 
|  | 63   Entry* entry = it->second; | 
|  | 64   if (request_time < entry->throttled_time) | 
|  | 65     return true; | 
|  | 66   // Allow one request between throttled_time and release_time. | 
|  | 67   if (request_time >= entry->throttled_time && | 
|  | 68       request_time < entry->release_time) { | 
|  | 69     if (entry->used) | 
|  | 70       return true; | 
|  | 71     entry->used = true; | 
|  | 72   } | 
|  | 73   return false; | 
|  | 74 } | 
|  | 75 | 
|  | 76 void URLRequestBackoffManager::OnIPAddressChanged() { | 
|  | 77   OnNetworkChange(); | 
|  | 78 } | 
|  | 79 | 
|  | 80 void URLRequestBackoffManager::OnConnectionTypeChanged( | 
|  | 81     NetworkChangeNotifier::ConnectionType type) { | 
|  | 82   OnNetworkChange(); | 
|  | 83 } | 
|  | 84 | 
|  | 85 int URLRequestBackoffManager::GetNumberOfEntriesForTests() const { | 
|  | 86   return url_entries_.size(); | 
|  | 87 } | 
|  | 88 | 
|  | 89 void URLRequestBackoffManager::GarbageCollectEntriesIfNecessary() { | 
|  | 90   CalledOnValidThread(); | 
|  | 91   if (new_entries_since_last_gc_ < kNewEntriesBetweenCollecting) | 
|  | 92     return; | 
|  | 93 | 
|  | 94   new_entries_since_last_gc_ = 0; | 
|  | 95   UrlEntryMap::iterator it = url_entries_.begin(); | 
|  | 96   while (it != url_entries_.end()) { | 
|  | 97     Entry* entry = it->second; | 
|  | 98     if (entry->IsOutDated()) { | 
|  | 99       url_entries_.erase(it++); | 
|  | 100       delete entry; | 
|  | 101     } else { | 
|  | 102       ++it; | 
|  | 103     } | 
|  | 104   } | 
|  | 105 } | 
|  | 106 | 
|  | 107 bool URLRequestBackoffManager::GetBackoffTime(HttpResponseHeaders* headers, | 
|  | 108                                               base::TimeDelta* result) const { | 
|  | 109   base::StringPiece name("Backoff"); | 
|  | 110   std::string value; | 
|  | 111   void* iter = NULL; | 
|  | 112   while (headers->EnumerateHeader(&iter, name, &value)) { | 
|  | 113     int64 seconds; | 
|  | 114     base::StringToInt64(value, &seconds); | 
|  | 115     if (seconds >= kMinimumBackoffInSeconds && | 
|  | 116         seconds <= kMaximumBackoffInSeconds) { | 
|  | 117       *result = base::TimeDelta::FromSeconds(seconds); | 
|  | 118       return true; | 
|  | 119     } | 
|  | 120   } | 
|  | 121   return false; | 
|  | 122 } | 
|  | 123 | 
|  | 124 std::string URLRequestBackoffManager::GetIdFromUrl(const GURL& url) const { | 
|  | 125   if (!url.is_valid()) | 
|  | 126     return url.possibly_invalid_spec(); | 
|  | 127 | 
|  | 128   GURL id = url.ReplaceComponents(url_id_replacements_); | 
|  | 129   return base::StringToLowerASCII(id.spec()).c_str(); | 
|  | 130 } | 
|  | 131 | 
|  | 132 void URLRequestBackoffManager::OnNetworkChange() { | 
|  | 133   CalledOnValidThread(); | 
|  | 134 | 
|  | 135   new_entries_since_last_gc_ = 0; | 
|  | 136   // Remove all entries. | 
|  | 137   for (UrlEntryMap::iterator it = url_entries_.begin(); | 
|  | 138        it != url_entries_.end(); ++it) { | 
|  | 139     delete it->second; | 
|  | 140   } | 
|  | 141   url_entries_.clear(); | 
|  | 142 } | 
|  | 143 | 
|  | 144 }  // namespace net | 
| OLD | NEW | 
|---|