Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(737)

Unified Diff: net/url_request/url_request_backoff_manager.cc

Issue 1153093002: Implement URLRequestBackoffManager for managing Backoff headers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed tests Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/url_request/url_request_backoff_manager.cc
diff --git a/net/url_request/url_request_backoff_manager.cc b/net/url_request/url_request_backoff_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..51560e32981c90d13273e93db0476bb2901bde03
--- /dev/null
+++ b/net/url_request/url_request_backoff_manager.cc
@@ -0,0 +1,144 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/url_request/url_request_backoff_manager.h"
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
+#include "net/http/http_response_headers.h"
+
+namespace net {
+
+const uint16 URLRequestBackoffManager::kMinimumBackoffInSeconds = 1;
+const uint16 URLRequestBackoffManager::kMaximumBackoffInSeconds = 50000;
+const uint16 URLRequestBackoffManager::kNewEntriesBetweenCollecting = 200;
+
+URLRequestBackoffManager::URLRequestBackoffManager()
+ : new_entries_since_last_gc_(0) {
+ url_id_replacements_.ClearPassword();
+ url_id_replacements_.ClearUsername();
+ url_id_replacements_.ClearQuery();
+ url_id_replacements_.ClearRef();
+
+ NetworkChangeNotifier::AddIPAddressObserver(this);
+ NetworkChangeNotifier::AddConnectionTypeObserver(this);
+}
+
+URLRequestBackoffManager::~URLRequestBackoffManager() {
+ NetworkChangeNotifier::RemoveIPAddressObserver(this);
+ NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
+ for (UrlEntryMap::iterator it = url_entries_.begin();
+ it != url_entries_.end(); ++it) {
+ delete it->second;
+ }
+ url_entries_.clear();
+}
+
+void URLRequestBackoffManager::UpdateWithResponse(
+ const GURL& url,
+ HttpResponseHeaders* headers,
+ const base::Time& response_time) {
+ CalledOnValidThread();
+ base::TimeDelta result;
+ if (GetBackoffTime(headers, &result)) {
+ new_entries_since_last_gc_++;
+ std::string url_id = GetIdFromUrl(url);
+ url_entries_[url_id] =
+ new Entry(response_time + result, response_time + result * 1.1);
+ GarbageCollectEntriesIfNecessary();
+ }
+}
+
+bool URLRequestBackoffManager::ShouldRejectRequest(
+ const GURL& url,
+ const base::Time& request_time) {
+ CalledOnValidThread();
+ std::string url_id = GetIdFromUrl(url);
+ UrlEntryMap::iterator it = url_entries_.find(url_id);
+ if (it == url_entries_.end())
+ return false;
+ Entry* entry = it->second;
+ if (request_time < entry->throttled_time)
+ return true;
+ // Allow one request between throttled_time and release_time.
+ if (request_time >= entry->throttled_time &&
+ request_time < entry->release_time) {
+ if (entry->used)
+ return true;
+ entry->used = true;
+ }
+ return false;
+}
+
+void URLRequestBackoffManager::OnIPAddressChanged() {
+ OnNetworkChange();
+}
+
+void URLRequestBackoffManager::OnConnectionTypeChanged(
+ NetworkChangeNotifier::ConnectionType type) {
+ OnNetworkChange();
+}
+
+int URLRequestBackoffManager::GetNumberOfEntriesForTests() const {
+ return url_entries_.size();
+}
+
+void URLRequestBackoffManager::GarbageCollectEntriesIfNecessary() {
+ CalledOnValidThread();
+ if (new_entries_since_last_gc_ < kNewEntriesBetweenCollecting)
+ return;
+
+ new_entries_since_last_gc_ = 0;
+ UrlEntryMap::iterator it = url_entries_.begin();
+ while (it != url_entries_.end()) {
+ Entry* entry = it->second;
+ if (entry->IsOutDated()) {
+ url_entries_.erase(it++);
+ delete entry;
+ } else {
+ ++it;
+ }
+ }
+}
+
+bool URLRequestBackoffManager::GetBackoffTime(HttpResponseHeaders* headers,
+ base::TimeDelta* result) const {
+ base::StringPiece name("Backoff");
+ std::string value;
+ void* iter = NULL;
+ while (headers->EnumerateHeader(&iter, name, &value)) {
+ int64 seconds;
+ base::StringToInt64(value, &seconds);
+ if (seconds >= kMinimumBackoffInSeconds &&
+ seconds <= kMaximumBackoffInSeconds) {
+ *result = base::TimeDelta::FromSeconds(seconds);
+ return true;
+ }
+ }
+ return false;
+}
+
+std::string URLRequestBackoffManager::GetIdFromUrl(const GURL& url) const {
+ if (!url.is_valid())
+ return url.possibly_invalid_spec();
+
+ GURL id = url.ReplaceComponents(url_id_replacements_);
+ return base::StringToLowerASCII(id.spec()).c_str();
+}
+
+void URLRequestBackoffManager::OnNetworkChange() {
+ CalledOnValidThread();
+
+ new_entries_since_last_gc_ = 0;
+ // Remove all entries.
+ for (UrlEntryMap::iterator it = url_entries_.begin();
+ it != url_entries_.end(); ++it) {
+ delete it->second;
+ }
+ url_entries_.clear();
+}
+
+} // namespace net
« no previous file with comments | « net/url_request/url_request_backoff_manager.h ('k') | net/url_request/url_request_backoff_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698