Home | History | Annotate | Download | only in url_request
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef NET_URL_REQUEST_URL_REQUEST_THROTTLER_MANAGER_H_
      6 #define NET_URL_REQUEST_URL_REQUEST_THROTTLER_MANAGER_H_
      7 
      8 #include <map>
      9 #include <set>
     10 #include <string>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/threading/non_thread_safe.h"
     15 #include "base/threading/platform_thread.h"
     16 #include "net/base/net_export.h"
     17 #include "net/base/network_change_notifier.h"
     18 #include "net/url_request/url_request_throttler_entry.h"
     19 #include "url/gurl.h"
     20 
     21 namespace net {
     22 
     23 class BoundNetLog;
     24 class NetLog;
     25 
     26 // Class that registers URL request throttler entries for URLs being accessed
     27 // in order to supervise traffic. URL requests for HTTP contents should
     28 // register their URLs in this manager on each request.
     29 //
     30 // URLRequestThrottlerManager maintains a map of URL IDs to URL request
     31 // throttler entries. It creates URL request throttler entries when new URLs
     32 // are registered, and does garbage collection from time to time in order to
     33 // clean out outdated entries. URL ID consists of lowercased scheme, host, port
     34 // and path. All URLs converted to the same ID will share the same entry.
     35 class NET_EXPORT URLRequestThrottlerManager
     36     : NON_EXPORTED_BASE(public base::NonThreadSafe),
     37       public NetworkChangeNotifier::IPAddressObserver,
     38       public NetworkChangeNotifier::ConnectionTypeObserver {
     39  public:
     40   URLRequestThrottlerManager();
     41   virtual ~URLRequestThrottlerManager();
     42 
     43   // Must be called for every request, returns the URL request throttler entry
     44   // associated with the URL. The caller must inform this entry of some events.
     45   // Please refer to url_request_throttler_entry_interface.h for further
     46   // informations.
     47   scoped_refptr<URLRequestThrottlerEntryInterface> RegisterRequestUrl(
     48       const GURL& url);
     49 
     50   // Adds the given host to a list of sites for which exponential back-off
     51   // throttling will be disabled.  Subdomains are not included, so they
     52   // must be added separately.
     53   void AddToOptOutList(const std::string& host);
     54 
     55   // Registers a new entry in this service and overrides the existing entry (if
     56   // any) for the URL. The service will hold a reference to the entry.
     57   // It is only used by unit tests.
     58   void OverrideEntryForTests(const GURL& url, URLRequestThrottlerEntry* entry);
     59 
     60   // Explicitly erases an entry.
     61   // This is useful to remove those entries which have got infinite lifetime and
     62   // thus won't be garbage collected.
     63   // It is only used by unit tests.
     64   void EraseEntryForTests(const GURL& url);
     65 
     66   // Turns threading model verification on or off.  Any code that correctly
     67   // uses the network stack should preferably call this function to enable
     68   // verification of correct adherence to the network stack threading model.
     69   void set_enable_thread_checks(bool enable);
     70   bool enable_thread_checks() const;
     71 
     72   // Whether throttling is enabled or not.
     73   void set_enforce_throttling(bool enforce);
     74   bool enforce_throttling();
     75 
     76   // Sets the NetLog instance to use.
     77   void set_net_log(NetLog* net_log);
     78   NetLog* net_log() const;
     79 
     80   // IPAddressObserver interface.
     81   virtual void OnIPAddressChanged() OVERRIDE;
     82 
     83   // ConnectionTypeObserver interface.
     84   virtual void OnConnectionTypeChanged(
     85       NetworkChangeNotifier::ConnectionType type) OVERRIDE;
     86 
     87   // Method that allows us to transform a URL into an ID that can be used in our
     88   // map. Resulting IDs will be lowercase and consist of the scheme, host, port
     89   // and path (without query string, fragment, etc.).
     90   // If the URL is invalid, the invalid spec will be returned, without any
     91   // transformation.
     92   std::string GetIdFromUrl(const GURL& url) const;
     93 
     94   // Method that ensures the map gets cleaned from time to time. The period at
     95   // which garbage collecting happens is adjustable with the
     96   // kRequestBetweenCollecting constant.
     97   void GarbageCollectEntriesIfNecessary();
     98 
     99   // Method that does the actual work of garbage collecting.
    100   void GarbageCollectEntries();
    101 
    102   // When we switch from online to offline or change IP addresses, we
    103   // clear all back-off history. This is a precaution in case the change in
    104   // online state now lets us communicate without error with servers that
    105   // we were previously getting 500 or 503 responses from (perhaps the
    106   // responses are from a badly-written proxy that should have returned a
    107   // 502 or 504 because it's upstream connection was down or it had no route
    108   // to the server).
    109   void OnNetworkChange();
    110 
    111   // Used by tests.
    112   int GetNumberOfEntriesForTests() const { return url_entries_.size(); }
    113 
    114  private:
    115   // From each URL we generate an ID composed of the scheme, host, port and path
    116   // that allows us to uniquely map an entry to it.
    117   typedef std::map<std::string, scoped_refptr<URLRequestThrottlerEntry> >
    118       UrlEntryMap;
    119 
    120   // We maintain a set of hosts that have opted out of exponential
    121   // back-off throttling.
    122   typedef std::set<std::string> OptOutHosts;
    123 
    124   // Maximum number of entries that we are willing to collect in our map.
    125   static const unsigned int kMaximumNumberOfEntries;
    126   // Number of requests that will be made between garbage collection.
    127   static const unsigned int kRequestsBetweenCollecting;
    128 
    129   // Map that contains a list of URL ID and their matching
    130   // URLRequestThrottlerEntry.
    131   UrlEntryMap url_entries_;
    132 
    133   // Set of hosts that have opted out.
    134   OptOutHosts opt_out_hosts_;
    135 
    136   // This keeps track of how many requests have been made. Used with
    137   // GarbageCollectEntries.
    138   unsigned int requests_since_last_gc_;
    139 
    140   // Valid after construction.
    141   GURL::Replacements url_id_replacements_;
    142 
    143   // Certain tests do not obey the net component's threading policy, so we
    144   // keep track of whether we're being used by tests, and turn off certain
    145   // checks.
    146   //
    147   // TODO(joi): See if we can fix the offending unit tests and remove this
    148   // workaround.
    149   bool enable_thread_checks_;
    150 
    151   // Initially false, switches to true once we have logged because of back-off
    152   // being disabled for localhost.
    153   bool logged_for_localhost_disabled_;
    154 
    155   // NetLog to use, if configured.
    156   BoundNetLog net_log_;
    157 
    158   // Valid once we've registered for network notifications.
    159   base::PlatformThreadId registered_from_thread_;
    160 
    161   DISALLOW_COPY_AND_ASSIGN(URLRequestThrottlerManager);
    162 };
    163 
    164 }  // namespace net
    165 
    166 #endif  // NET_URL_REQUEST_URL_REQUEST_THROTTLER_MANAGER_H_
    167