diff options
author | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 13:21:15 +0000 |
---|---|---|
committer | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 13:21:15 +0000 |
commit | a1d4ab0736c3706165d284fa76c95d67f6ab3bf9 (patch) | |
tree | a2e9d0d10c021aee60ab59d2619750546785654b | |
parent | 54acdbf5115fb8ff7484a822ee98af1615977da0 (diff) | |
download | chromium_src-a1d4ab0736c3706165d284fa76c95d67f6ab3bf9.zip chromium_src-a1d4ab0736c3706165d284fa76c95d67f6ab3bf9.tar.gz chromium_src-a1d4ab0736c3706165d284fa76c95d67f6ab3bf9.tar.bz2 |
Introduce a delegate to avoid hardcoding "chrome-extension" in net/.
Also, deal with a couple of TODOs in the throttling code, and remove
metrics we no longer need since we are no longer running field trials
for this code.
BUG=119760
Review URL: https://chromiumcodereview.appspot.com/10440119
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141000 0039d316-1c4b-4281-b951-d872f2087c98
21 files changed, 147 insertions, 130 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 4bdc0aa..e252afa 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -395,13 +395,18 @@ void IOThread::Init() { globals_->extension_event_router_forwarder = extension_event_router_forwarder_; - globals_->system_network_delegate.reset(new ChromeNetworkDelegate( + ChromeNetworkDelegate* network_delegate = new ChromeNetworkDelegate( extension_event_router_forwarder_, NULL, NULL, NULL, NULL, - &system_enable_referrers_)); + &system_enable_referrers_); + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableExtensionsHttpThrottling)) { + network_delegate->NeverThrottleRequests(); + } + globals_->system_network_delegate.reset(network_delegate); globals_->host_resolver.reset( CreateGlobalHostResolver(net_log_)); globals_->cert_verifier.reset(net::CertVerifier::CreateDefault()); @@ -447,13 +452,9 @@ void IOThread::Init() { new net::FtpNetworkLayer(globals_->host_resolver.get())); globals_->throttler_manager.reset(new net::URLRequestThrottlerManager()); + globals_->throttler_manager->set_net_log(net_log_); // Always done in production, disabled only for unit tests. globals_->throttler_manager->set_enable_thread_checks(true); - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableExtensionsHttpThrottling)) { - globals_->throttler_manager->set_enforce_throttling(false); - } - globals_->throttler_manager->set_net_log(net_log_); globals_->proxy_script_fetcher_context.reset( ConstructProxyScriptFetcherContext(globals_, net_log_)); diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc index 9abf6c4..6ea4eb8 100644 --- a/chrome/browser/net/chrome_network_delegate.cc +++ b/chrome/browser/net/chrome_network_delegate.cc @@ -18,6 +18,7 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/task_manager/task_manager.h" #include "chrome/common/pref_names.h" +#include "chrome/common/url_constants.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_request_info.h" @@ -129,6 +130,7 @@ ChromeNetworkDelegate::ChromeNetworkDelegate( cookie_settings_(cookie_settings), extension_info_map_(extension_info_map), enable_referrers_(enable_referrers), + never_throttle_requests_(false), url_blacklist_manager_(url_blacklist_manager) { DCHECK(event_router); DCHECK(enable_referrers); @@ -137,6 +139,10 @@ ChromeNetworkDelegate::ChromeNetworkDelegate( ChromeNetworkDelegate::~ChromeNetworkDelegate() {} +void ChromeNetworkDelegate::NeverThrottleRequests() { + never_throttle_requests_ = true; +} + // static void ChromeNetworkDelegate::InitializeReferrersEnabled( BooleanPrefMember* enable_referrers, @@ -354,3 +360,13 @@ bool ChromeNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, return true; #endif // defined(OS_CHROMEOS) } + +bool ChromeNetworkDelegate::OnCanThrottleRequest( + const net::URLRequest& request) const { + if (never_throttle_requests_) { + return false; + } + + return request.first_party_for_cookies().scheme() != + chrome::kExtensionScheme; +} diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h index dda92d5..2ff6843 100644 --- a/chrome/browser/net/chrome_network_delegate.h +++ b/chrome/browser/net/chrome_network_delegate.h @@ -42,6 +42,9 @@ class ChromeNetworkDelegate : public net::NetworkDelegate { BooleanPrefMember* enable_referrers); virtual ~ChromeNetworkDelegate(); + // Causes |OnCanThrottleRequest| to never return true. + void NeverThrottleRequests(); + // Binds |enable_referrers| to |pref_service| and moves it to the IO thread. // This method should be called on the UI thread. static void InitializeReferrersEnabled(BooleanPrefMember* enable_referrers, @@ -88,6 +91,8 @@ class ChromeNetworkDelegate : public net::NetworkDelegate { net::CookieOptions* options) OVERRIDE; virtual bool OnCanAccessFile(const net::URLRequest& request, const FilePath& path) const OVERRIDE; + virtual bool OnCanThrottleRequest( + const net::URLRequest& request) const OVERRIDE; scoped_refptr<ExtensionEventRouterForwarder> event_router_; void* profile_; @@ -98,6 +103,9 @@ class ChromeNetworkDelegate : public net::NetworkDelegate { // Weak, owned by our owner. BooleanPrefMember* enable_referrers_; + // True if OnCanThrottleRequest should always return false. + bool never_throttle_requests_; + // Weak, owned by our owner. const policy::URLBlacklistManager* url_blacklist_manager_; diff --git a/content/shell/shell_network_delegate.cc b/content/shell/shell_network_delegate.cc index 1faa68d..66f6600 100644 --- a/content/shell/shell_network_delegate.cc +++ b/content/shell/shell_network_delegate.cc @@ -86,4 +86,9 @@ bool ShellNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, return true; } +bool ShellNetworkDelegate::OnCanThrottleRequest( + const net::URLRequest& request) const { + return false; +} + } // namespace content diff --git a/content/shell/shell_network_delegate.h b/content/shell/shell_network_delegate.h index 9b3de66..d08d5cf 100644 --- a/content/shell/shell_network_delegate.h +++ b/content/shell/shell_network_delegate.h @@ -54,6 +54,8 @@ class ShellNetworkDelegate : public net::NetworkDelegate { net::CookieOptions* options) OVERRIDE; virtual bool OnCanAccessFile(const net::URLRequest& request, const FilePath& path) const OVERRIDE; + virtual bool OnCanThrottleRequest( + const net::URLRequest& request) const OVERRIDE; DISALLOW_COPY_AND_ASSIGN(ShellNetworkDelegate); }; diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc index 79ad701..c3fd9e6 100644 --- a/net/base/network_delegate.cc +++ b/net/base/network_delegate.cc @@ -113,4 +113,9 @@ bool NetworkDelegate::CanAccessFile(const URLRequest& request, return OnCanAccessFile(request, path); } +bool NetworkDelegate::CanThrottleRequest(const URLRequest& request) const { + DCHECK(CalledOnValidThread()); + return OnCanThrottleRequest(request); +} + } // namespace net diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h index 2886d48..4d56e3f 100644 --- a/net/base/network_delegate.h +++ b/net/base/network_delegate.h @@ -85,6 +85,7 @@ class NetworkDelegate : public base::NonThreadSafe { CookieOptions* options); bool CanAccessFile(const URLRequest& request, const FilePath& path) const; + bool CanThrottleRequest(const URLRequest& request) const; private: // This is the interface for subclasses of NetworkDelegate to implement. These @@ -202,6 +203,10 @@ class NetworkDelegate : public base::NonThreadSafe { virtual bool OnCanAccessFile(const URLRequest& request, const FilePath& path) const = 0; + // Returns true if the given request may be rejected when the + // URLRequestThrottlerManager believes the server servicing the + // request is overloaded or down. + virtual bool OnCanThrottleRequest(const URLRequest& request) const = 0; }; } // namespace net diff --git a/net/proxy/network_delegate_error_observer_unittest.cc b/net/proxy/network_delegate_error_observer_unittest.cc index 7c8efdf..882fba9 100644 --- a/net/proxy/network_delegate_error_observer_unittest.cc +++ b/net/proxy/network_delegate_error_observer_unittest.cc @@ -76,6 +76,9 @@ class TestNetworkDelegate : public net::NetworkDelegate { const FilePath& path) const OVERRIDE { return true; } + virtual bool OnCanThrottleRequest(const URLRequest& request) const OVERRIDE { + return false; + } bool got_pac_error_; }; diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc index 9e9187a..8a3673d 100644 --- a/net/proxy/proxy_script_fetcher_impl_unittest.cc +++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc @@ -183,6 +183,9 @@ class BasicNetworkDelegate : public NetworkDelegate { const FilePath& path) const OVERRIDE { return true; } + virtual bool OnCanThrottleRequest(const URLRequest& request) const OVERRIDE { + return false; + } DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate); }; diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc index b08904e..23820d8 100644 --- a/net/url_request/url_request_context_builder.cc +++ b/net/url_request/url_request_context_builder.cc @@ -101,6 +101,10 @@ class BasicNetworkDelegate : public NetworkDelegate { return true; } + virtual bool OnCanThrottleRequest(const URLRequest& request) const OVERRIDE { + return false; + } + DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate); }; diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 1fd4f8b..8491594 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -307,18 +307,8 @@ void URLRequestHttpJob::StartTransactionInternal() { rv = request_->context()->http_transaction_factory()->CreateTransaction( &transaction_); if (rv == OK) { - // TODO(joi): The hard-coded check for "chrome-extension" is - // temporary (as of 2012/3/21), intended only to make sure this - // change (to throttle only requests originating from - // extensions) gets into M19. Right after the M19 branch point, - // I will sort this out in a more architecturally-sound way. - URLRequestThrottlerManager* manager = - request_->context()->throttler_manager(); - DCHECK(!manager || throttling_entry_); - if (!manager || - !manager->enforce_throttling() || - request_->first_party_for_cookies().scheme() != "chrome-extension" || - !throttling_entry_->ShouldRejectRequest(request_info_.load_flags)) { + if (!throttling_entry_ || + !throttling_entry_->ShouldRejectRequest(*request_)) { rv = transaction_->Start( &request_info_, start_callback_, request_->net_log()); start_time_ = base::TimeTicks::Now(); diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index 11eda37..6374bda 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc @@ -493,6 +493,11 @@ bool TestNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, return true; } +bool TestNetworkDelegate::OnCanThrottleRequest( + const net::URLRequest& request) const { + return true; +} + // static std::string ScopedCustomUrlRequestTestHttpHost::value_("127.0.0.1"); diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h index 26ce942..90a074b 100644 --- a/net/url_request/url_request_test_util.h +++ b/net/url_request/url_request_test_util.h @@ -244,6 +244,8 @@ class TestNetworkDelegate : public net::NetworkDelegate { net::CookieOptions* options) OVERRIDE; virtual bool OnCanAccessFile(const net::URLRequest& request, const FilePath& path) const OVERRIDE; + virtual bool OnCanThrottleRequest( + const net::URLRequest& request) const OVERRIDE; void InitRequestStatesIfNew(int request_id); diff --git a/net/url_request/url_request_throttler_entry.cc b/net/url_request/url_request_throttler_entry.cc index 60c6154..b0f519d 100644 --- a/net/url_request/url_request_throttler_entry.cc +++ b/net/url_request/url_request_throttler_entry.cc @@ -14,6 +14,8 @@ #include "base/values.h" #include "net/base/load_flags.h" #include "net/base/net_log.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" #include "net/url_request/url_request_throttler_header_interface.h" #include "net/url_request/url_request_throttler_manager.h" @@ -138,8 +140,10 @@ bool URLRequestThrottlerEntry::IsEntryOutdated() const { // if an entry has more than one reference (the map will always hold one), // it should not be considered outdated. // - // TODO(joi): Once the manager is not a Singleton, revisit whether - // refcounting is needed at all. + // We considered whether to make URLRequestThrottlerEntry objects + // non-refcounted, but since any means of knowing whether they are + // currently in use by others than the manager would be more or less + // equivalent to a refcount, we kept them refcounted. if (!HasOneRef()) return false; @@ -161,9 +165,12 @@ void URLRequestThrottlerEntry::DetachManager() { manager_ = NULL; } -bool URLRequestThrottlerEntry::ShouldRejectRequest(int load_flags) const { +bool URLRequestThrottlerEntry::ShouldRejectRequest( + const URLRequest& request) const { bool reject_request = false; - if (!is_backoff_disabled_ && !ExplicitUserRequest(load_flags) && + if (!is_backoff_disabled_ && !ExplicitUserRequest(request.load_flags()) && + (!request.context() || !request.context()->network_delegate() || + request.context()->network_delegate()->CanThrottleRequest(request)) && GetBackoffEntry()->ShouldRejectRequest()) { int num_failures = GetBackoffEntry()->failure_count(); int release_after_ms = @@ -237,10 +244,7 @@ base::TimeTicks void URLRequestThrottlerEntry::UpdateWithResponse( const std::string& host, const URLRequestThrottlerHeaderInterface* response) { - int response_code = response->GetResponseCode(); - HandleMetricsTracking(response_code); - - if (IsConsideredError(response_code)) { + if (IsConsideredError(response->GetResponseCode())) { GetBackoffEntry()->InformOfRequest(false); } else { GetBackoffEntry()->InformOfRequest(true); @@ -280,12 +284,6 @@ void URLRequestThrottlerEntry::Initialize() { backoff_policy_.maximum_backoff_ms = kDefaultMaximumBackoffMs; backoff_policy_.entry_lifetime_ms = kDefaultEntryLifetimeMs; backoff_policy_.always_use_initial_delay = false; - - // We pretend we just had a successful response so that we have a - // starting point to our tracking. This is called from the - // constructor so we do not use the virtual ImplGetTimeNow(). - last_successful_response_time_ = base::TimeTicks::Now(); - last_response_was_success_ = true; } bool URLRequestThrottlerEntry::IsConsideredError(int response_code) { @@ -322,34 +320,6 @@ void URLRequestThrottlerEntry::HandleThrottlingHeader( DisableBackoffThrottling(); if (manager_) manager_->AddToOptOutList(host); - } else { - // TODO(joi): Log this. - } -} - -void URLRequestThrottlerEntry::HandleMetricsTracking(int response_code) { - // Note that we are not interested in whether the code is considered - // an error for the backoff logic, but whether it is a 5xx error in - // general. This is because here, we are tracking the apparent total - // downtime of a server. - if (response_code >= 500) { - last_response_was_success_ = false; - } else { - base::TimeTicks now = ImplGetTimeNow(); - if (!last_response_was_success_) { - // We are transitioning from failure to success, so generate our stats. - base::TimeDelta down_time = now - last_successful_response_time_; - int failure_count = GetBackoffEntry()->failure_count(); - - UMA_HISTOGRAM_COUNTS("Throttling.FailureCountAtSuccess", failure_count); - UMA_HISTOGRAM_CUSTOM_TIMES( - "Throttling.PerceivedDowntime", down_time, - base::TimeDelta::FromMilliseconds(10), - base::TimeDelta::FromHours(6), 50); - } - - last_successful_response_time_ = now; - last_response_was_success_ = true; } } diff --git a/net/url_request/url_request_throttler_entry.h b/net/url_request/url_request_throttler_entry.h index 3ebd5c9..e5399c9 100644 --- a/net/url_request/url_request_throttler_entry.h +++ b/net/url_request/url_request_throttler_entry.h @@ -93,7 +93,7 @@ class NET_EXPORT URLRequestThrottlerEntry void DetachManager(); // Implementation of URLRequestThrottlerEntryInterface. - virtual bool ShouldRejectRequest(int load_flags) const OVERRIDE; + virtual bool ShouldRejectRequest(const URLRequest& request) const OVERRIDE; virtual int64 ReserveSendingTimeForNextRequest( const base::TimeTicks& earliest_time) OVERRIDE; virtual base::TimeTicks GetExponentialBackoffReleaseTime() const OVERRIDE; @@ -118,10 +118,6 @@ class NET_EXPORT URLRequestThrottlerEntry void HandleThrottlingHeader(const std::string& header_value, const std::string& host); - // Used internally to keep track of failure->success transitions and - // generate statistics about them. - void HandleMetricsTracking(int response_code); - // Retrieves the back-off entry object we're using. Used to enable a // unit testing seam for dependency injection in tests. virtual const BackoffEntry* GetBackoffEntry() const; @@ -164,15 +160,6 @@ class NET_EXPORT URLRequestThrottlerEntry // Access it through GetBackoffEntry() to allow a unit test seam. BackoffEntry backoff_entry_; - // The time of the last successful response, plus knowledge of whether - // the last response was successful or not, let us generate statistics on - // the length of perceived downtime for a given URL, and the error count - // when such transitions occur. This is useful for experiments with - // throttling but will likely become redundant after they are finished. - // TODO(joi): Remove when the time is right - base::TimeTicks last_successful_response_time_; - bool last_response_was_success_; - // Weak back-reference to the manager object managing us. URLRequestThrottlerManager* manager_; diff --git a/net/url_request/url_request_throttler_entry_interface.h b/net/url_request/url_request_throttler_entry_interface.h index e46cd2a..ea236b4 100644 --- a/net/url_request/url_request_throttler_entry_interface.h +++ b/net/url_request/url_request_throttler_entry_interface.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -15,6 +15,7 @@ namespace net { +class URLRequest; class URLRequestThrottlerHeaderInterface; // Interface provided on entries of the URL request throttler manager. @@ -24,13 +25,13 @@ class NET_EXPORT URLRequestThrottlerEntryInterface URLRequestThrottlerEntryInterface() {} // Returns true when we have encountered server errors and are doing - // exponential back-off, unless the request has |load_flags| (from - // net/base/load_flags.h) that mean it is likely to be - // user-initiated. + // exponential back-off, unless the request has load flags that mean + // it is likely to be user-initiated, or the NetworkDelegate returns + // false for |CanThrottleRequest(request)|. // // URLRequestHttpJob checks this method prior to every request; it // cancels requests if this method returns true. - virtual bool ShouldRejectRequest(int load_flags) const = 0; + virtual bool ShouldRejectRequest(const URLRequest& request) const = 0; // Calculates a recommended sending time for the next request and reserves it. // The sending time is not earlier than the current exponential back-off diff --git a/net/url_request/url_request_throttler_manager.cc b/net/url_request/url_request_throttler_manager.cc index 5c50558..6d26510 100644 --- a/net/url_request/url_request_throttler_manager.cc +++ b/net/url_request/url_request_throttler_manager.cc @@ -18,7 +18,6 @@ const unsigned int URLRequestThrottlerManager::kRequestsBetweenCollecting = 200; URLRequestThrottlerManager::URLRequestThrottlerManager() : requests_since_last_gc_(0), - enforce_throttling_(true), enable_thread_checks_(false), logged_for_localhost_disabled_(false), registered_from_thread_(base::kInvalidThreadId) { @@ -35,10 +34,8 @@ URLRequestThrottlerManager::~URLRequestThrottlerManager() { NetworkChangeNotifier::RemoveIPAddressObserver(this); NetworkChangeNotifier::RemoveConnectionTypeObserver(this); - // Since, for now, the manager object might conceivably go away before - // the entries, detach the entries' back-pointer to the manager. - // - // TODO(joi): Revisit whether to make entries non-refcounted. + // Since the manager object might conceivably go away before the + // entries, detach the entries' back-pointer to the manager. UrlEntryMap::iterator i = url_entries_.begin(); while (i != url_entries_.end()) { if (i->second != NULL) { @@ -144,14 +141,6 @@ bool URLRequestThrottlerManager::enable_thread_checks() const { return enable_thread_checks_; } -void URLRequestThrottlerManager::set_enforce_throttling(bool enforce) { - enforce_throttling_ = enforce; -} - -bool URLRequestThrottlerManager::enforce_throttling() { - return enforce_throttling_; -} - void URLRequestThrottlerManager::set_net_log(NetLog* net_log) { DCHECK(net_log); net_log_ = BoundNetLog::Make(net_log, diff --git a/net/url_request/url_request_throttler_manager.h b/net/url_request/url_request_throttler_manager.h index 427b42e..d438f67 100644 --- a/net/url_request/url_request_throttler_manager.h +++ b/net/url_request/url_request_throttler_manager.h @@ -141,10 +141,6 @@ class NET_EXPORT URLRequestThrottlerManager // Valid after construction. GURL::Replacements url_id_replacements_; - // Whether we would like to reject outgoing HTTP requests during the back-off - // period. - bool enforce_throttling_; - // Certain tests do not obey the net component's threading policy, so we // keep track of whether we're being used by tests, and turn off certain // checks. diff --git a/net/url_request/url_request_throttler_simulation_unittest.cc b/net/url_request/url_request_throttler_simulation_unittest.cc index 256d343..b13e67c 100644 --- a/net/url_request/url_request_throttler_simulation_unittest.cc +++ b/net/url_request/url_request_throttler_simulation_unittest.cc @@ -20,6 +20,7 @@ #include "base/memory/scoped_vector.h" #include "base/rand_util.h" #include "base/time.h" +#include "net/url_request/url_request_test_util.h" #include "net/url_request/url_request_throttler_manager.h" #include "net/url_request/url_request_throttler_test_support.h" #include "testing/gtest/include/gtest/gtest.h" @@ -122,7 +123,8 @@ class Server : public DiscreteTimeSimulation::Actor { num_overloaded_ticks_remaining_(0), num_current_tick_queries_(0), num_overloaded_ticks_(0), - max_experienced_queries_per_tick_(0) { + max_experienced_queries_per_tick_(0), + mock_request_(GURL(), NULL) { } void SetDowntime(const TimeTicks& start_time, const TimeDelta& duration) { @@ -159,7 +161,7 @@ class Server : public DiscreteTimeSimulation::Actor { ++num_current_tick_queries_; if (!start_downtime_.is_null() && start_downtime_ < now_ && now_ < end_downtime_) { - // TODO(joi): For the simulation measuring the increase in perceived + // For the simulation measuring the increase in perceived // downtime, it might be interesting to count separately the // queries seen by the server (assuming a front-end reverse proxy // is what actually serves up the 503s in this case) so that we could @@ -186,6 +188,10 @@ class Server : public DiscreteTimeSimulation::Actor { return max_experienced_queries_per_tick_; } + const URLRequest& mock_request() const { + return mock_request_; + } + std::string VisualizeASCII(int terminal_width) { // Account for | characters we place at left of graph. terminal_width -= 1; @@ -281,16 +287,11 @@ class Server : public DiscreteTimeSimulation::Actor { int num_overloaded_ticks_; int max_experienced_queries_per_tick_; std::vector<int> requests_per_tick_; + TestURLRequest mock_request_; DISALLOW_COPY_AND_ASSIGN(Server); }; -class TestingURLRequestThrottlerManager : public URLRequestThrottlerManager { - public: - TestingURLRequestThrottlerManager() : URLRequestThrottlerManager() { - } -}; - // Mock throttler entry used by Requester class. class MockURLRequestThrottlerEntry : public URLRequestThrottlerEntry { public: @@ -427,7 +428,7 @@ class Requester : public DiscreteTimeSimulation::Actor { if (throttler_entry_->fake_now() - time_of_last_attempt_ > effective_delay) { - if (!throttler_entry_->ShouldRejectRequest(0)) { + if (!throttler_entry_->ShouldRejectRequest(server_->mock_request())) { int status_code = server_->HandleRequest(); MockURLRequestThrottlerHeaderAdapter response_headers(status_code); throttler_entry_->UpdateWithResponse("", &response_headers); @@ -493,7 +494,7 @@ void SimulateAttack(Server* server, const size_t kNumAttackers = 50; const size_t kNumClients = 50; DiscreteTimeSimulation simulation; - TestingURLRequestThrottlerManager manager; + URLRequestThrottlerManager manager; ScopedVector<Requester> requesters; for (size_t i = 0; i < kNumAttackers; ++i) { // Use a tiny time_between_requests so the attackers will ping the @@ -596,7 +597,7 @@ double SimulateDowntime(const TimeDelta& duration, Server server(std::numeric_limits<int>::max(), 1.0); server.SetDowntime(start_downtime, duration); - TestingURLRequestThrottlerManager manager; + URLRequestThrottlerManager manager; scoped_refptr<MockURLRequestThrottlerEntry> throttler_entry( new MockURLRequestThrottlerEntry(&manager)); if (!enable_throttling) diff --git a/net/url_request/url_request_throttler_unittest.cc b/net/url_request/url_request_throttler_unittest.cc index 0d018cd..9a6079d 100644 --- a/net/url_request/url_request_throttler_unittest.cc +++ b/net/url_request/url_request_throttler_unittest.cc @@ -13,6 +13,7 @@ #include "net/base/load_flags.h" #include "net/base/test_completion_callback.h" #include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_test_util.h" #include "net/url_request/url_request_throttler_header_interface.h" #include "net/url_request/url_request_throttler_test_support.h" #include "testing/gtest/include/gtest/gtest.h" @@ -166,6 +167,9 @@ struct GurlAndString { class URLRequestThrottlerEntryTest : public testing::Test { protected: + URLRequestThrottlerEntryTest() : request_(GURL(), NULL) { + } + virtual void SetUp(); // After calling this function, histogram snapshots in |samples_| contain @@ -178,6 +182,8 @@ class URLRequestThrottlerEntryTest : public testing::Test { std::map<std::string, Histogram::SampleSet> original_samples_; std::map<std::string, Histogram::SampleSet> samples_; + + TestURLRequest request_; }; // List of all histograms we care about in these unit tests. @@ -189,6 +195,8 @@ const char* kHistogramNames[] = { }; void URLRequestThrottlerEntryTest::SetUp() { + request_.set_load_flags(0); + now_ = TimeTicks::Now(); entry_ = new MockURLRequestThrottlerEntry(&manager_); entry_->ResetToBlank(now_); @@ -234,10 +242,11 @@ std::ostream& operator<<(std::ostream& out, const base::TimeTicks& time) { TEST_F(URLRequestThrottlerEntryTest, InterfaceDuringExponentialBackoff) { entry_->set_exponential_backoff_release_time( entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1)); - EXPECT_TRUE(entry_->ShouldRejectRequest(0)); + EXPECT_TRUE(entry_->ShouldRejectRequest(request_)); // Also end-to-end test the load flags exceptions. - EXPECT_FALSE(entry_->ShouldRejectRequest(LOAD_MAYBE_USER_GESTURE)); + request_.set_load_flags(LOAD_MAYBE_USER_GESTURE); + EXPECT_FALSE(entry_->ShouldRejectRequest(request_)); CalculateHistogramDeltas(); ASSERT_EQ(1, samples_["Throttling.RequestThrottled"].counts(0)); @@ -246,10 +255,10 @@ TEST_F(URLRequestThrottlerEntryTest, InterfaceDuringExponentialBackoff) { TEST_F(URLRequestThrottlerEntryTest, InterfaceNotDuringExponentialBackoff) { entry_->set_exponential_backoff_release_time(entry_->fake_time_now_); - EXPECT_FALSE(entry_->ShouldRejectRequest(0)); + EXPECT_FALSE(entry_->ShouldRejectRequest(request_)); entry_->set_exponential_backoff_release_time( entry_->fake_time_now_ - TimeDelta::FromMilliseconds(1)); - EXPECT_FALSE(entry_->ShouldRejectRequest(0)); + EXPECT_FALSE(entry_->ShouldRejectRequest(request_)); CalculateHistogramDeltas(); ASSERT_EQ(2, samples_["Throttling.RequestThrottled"].counts(0)); @@ -278,10 +287,6 @@ TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccessThenFailure) { EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) << "This scenario should add delay"; entry_->UpdateWithResponse("", &success_response); - - CalculateHistogramDeltas(); - ASSERT_EQ(1, samples_["Throttling.FailureCountAtSuccess"].counts(1)); - ASSERT_EQ(1, samples_["Throttling.PerceivedDowntime"].TotalCount()); } TEST_F(URLRequestThrottlerEntryTest, IsEntryReallyOutdated) { @@ -371,7 +376,20 @@ TEST_F(URLRequestThrottlerEntryTest, ExplicitUserRequest) { ~LOAD_MAYBE_USER_GESTURE)); } -TEST(URLRequestThrottlerManager, IsUrlStandardised) { +class URLRequestThrottlerManagerTest : public testing::Test { + protected: + URLRequestThrottlerManagerTest() + : request_(GURL(), NULL) { + } + + virtual void SetUp() { + request_.set_load_flags(0); + } + + TestURLRequest request_; +}; + +TEST_F(URLRequestThrottlerManagerTest, IsUrlStandardised) { MockURLRequestThrottlerManager manager; GurlAndString test_values[] = { GurlAndString(GURL("http://www.example.com"), @@ -406,7 +424,7 @@ TEST(URLRequestThrottlerManager, IsUrlStandardised) { } } -TEST(URLRequestThrottlerManager, AreEntriesBeingCollected) { +TEST_F(URLRequestThrottlerManagerTest, AreEntriesBeingCollected) { MockURLRequestThrottlerManager manager; manager.CreateEntry(true); // true = Entry is outdated. @@ -423,7 +441,7 @@ TEST(URLRequestThrottlerManager, AreEntriesBeingCollected) { EXPECT_EQ(3, manager.GetNumberOfEntries()); } -TEST(URLRequestThrottlerManager, IsHostBeingRegistered) { +TEST_F(URLRequestThrottlerManagerTest, IsHostBeingRegistered) { MockURLRequestThrottlerManager manager; manager.RegisterRequestUrl(GURL("http://www.example.com/")); @@ -437,14 +455,15 @@ TEST(URLRequestThrottlerManager, IsHostBeingRegistered) { void ExpectEntryAllowsAllOnErrorIfOptedOut( net::URLRequestThrottlerEntryInterface* entry, - bool opted_out) { - EXPECT_FALSE(entry->ShouldRejectRequest(0)); + bool opted_out, + const URLRequest& request) { + EXPECT_FALSE(entry->ShouldRejectRequest(request)); MockURLRequestThrottlerHeaderAdapter failure_adapter(503); for (int i = 0; i < 10; ++i) { // Host doesn't really matter in this scenario so we skip it. entry->UpdateWithResponse("", &failure_adapter); } - EXPECT_NE(opted_out, entry->ShouldRejectRequest(0)); + EXPECT_NE(opted_out, entry->ShouldRejectRequest(request)); if (opted_out) { // We're not mocking out GetTimeNow() in this scenario @@ -460,7 +479,7 @@ void ExpectEntryAllowsAllOnErrorIfOptedOut( } } -TEST(URLRequestThrottlerManager, OptOutHeader) { +TEST_F(URLRequestThrottlerManagerTest, OptOutHeader) { MockURLRequestThrottlerManager manager; scoped_refptr<net::URLRequestThrottlerEntryInterface> entry = manager.RegisterRequestUrl(GURL("http://www.google.com/yodude")); @@ -473,28 +492,28 @@ TEST(URLRequestThrottlerManager, OptOutHeader) { entry->UpdateWithResponse("www.google.com", &response_adapter); // Ensure that the same entry on error always allows everything. - ExpectEntryAllowsAllOnErrorIfOptedOut(entry, true); + ExpectEntryAllowsAllOnErrorIfOptedOut(entry, true, request_); // Ensure that a freshly created entry (for a different URL on an // already opted-out host) also gets "always allow" behavior. scoped_refptr<net::URLRequestThrottlerEntryInterface> other_entry = manager.RegisterRequestUrl(GURL("http://www.google.com/bingobob")); - ExpectEntryAllowsAllOnErrorIfOptedOut(other_entry, true); + ExpectEntryAllowsAllOnErrorIfOptedOut(other_entry, true, request_); // Fake a response with the opt-out header incorrectly specified. scoped_refptr<net::URLRequestThrottlerEntryInterface> no_opt_out_entry = manager.RegisterRequestUrl(GURL("http://www.nike.com/justdoit")); MockURLRequestThrottlerHeaderAdapter wrong_adapter("", "yesplease", 200); no_opt_out_entry->UpdateWithResponse("www.nike.com", &wrong_adapter); - ExpectEntryAllowsAllOnErrorIfOptedOut(no_opt_out_entry, false); + ExpectEntryAllowsAllOnErrorIfOptedOut(no_opt_out_entry, false, request_); // A localhost entry should always be opted out. scoped_refptr<net::URLRequestThrottlerEntryInterface> localhost_entry = manager.RegisterRequestUrl(GURL("http://localhost/hello")); - ExpectEntryAllowsAllOnErrorIfOptedOut(localhost_entry, true); + ExpectEntryAllowsAllOnErrorIfOptedOut(localhost_entry, true, request_); } -TEST(URLRequestThrottlerManager, ClearOnNetworkChange) { +TEST_F(URLRequestThrottlerManagerTest, ClearOnNetworkChange) { for (int i = 0; i < 3; ++i) { MockURLRequestThrottlerManager manager; scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_before = @@ -504,7 +523,7 @@ TEST(URLRequestThrottlerManager, ClearOnNetworkChange) { // Host doesn't really matter in this scenario so we skip it. entry_before->UpdateWithResponse("", &failure_adapter); } - EXPECT_TRUE(entry_before->ShouldRejectRequest(0)); + EXPECT_TRUE(entry_before->ShouldRejectRequest(request_)); switch (i) { case 0: @@ -524,7 +543,7 @@ TEST(URLRequestThrottlerManager, ClearOnNetworkChange) { scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_after = manager.RegisterRequestUrl(GURL("http://www.example.com/")); - EXPECT_FALSE(entry_after->ShouldRejectRequest(0)); + EXPECT_FALSE(entry_after->ShouldRejectRequest(request_)); } } diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc index 450cbee..3847ff2 100644 --- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc +++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc @@ -177,6 +177,11 @@ class TestShellNetworkDelegate : public net::NetworkDelegate { const FilePath& path) const OVERRIDE { return true; } + virtual bool OnCanThrottleRequest( + const net::URLRequest& request) const OVERRIDE { + return false; + } + }; TestShellRequestContextParams* g_request_context_params = NULL; |